Brool brool (n.) : a low roar; a deep murmur or humming

Speeding Up flyspell-region

 |  coding

Flyspell-region is really, really slow on the Mac. You can literally watch it check a word, pause, check a word, pause…

Well, sometimes.

There are a few interesting things about this:

So, what’s going on?

Two things:

First, if the region is under a certain number of characters (see flyspell-large-region in flyspell.el, set to 1000 in the base version), Emacs will run flyspell-small-region instead of flyspell-large-region.

Second, flyspell-small-region is slow — much slower than flyspell-large-region. Look at the code for flyspell-small-region:

(defun flyspell-small-region (beg end)
  "Flyspell text between BEG and END."
    (if (> beg end)
    (let ((old beg))
      (setq beg end)
      (setq end old)))
    (goto-char beg)
    (let ((count 0))
      (while (< (point) end)
    (if (and flyspell-issue-message-flag (= count 100))
          (message "Spell Checking...%d%%"
               (* 100 (/ (float (- (point) beg)) (- end beg))))
          (setq count 0))
      (setq count (+ 1 count)))
    (sit-for 0)
    (let ((cur (point)))
      (forward-word 1)
      (if (and (< (point) end) (> (point) (+ cur 1)))
          (backward-char 1)))))
    (backward-char 1)
    (if flyspell-issue-message-flag (message "Spell Checking completed."))

The slow thing here is actually not the spell checking, it’s the sit-for call right after it. sit-for checks for input, but a side effect is that it forces a display refresh – which is fast in the terminal version of Emacs but slow in the GUI.

So, there are a couple ways of fixing this:

To remove it completely with advice, use something like this:

(defadvice flyspell-region (around fast-flyspell-region)
  (flet ( (sit-for (x) t) ) 
(ad-activate 'flyspell-region)

Suddenly, flyspell-region is not so slow anymore.


Comments are moderated whenever I remember that I have a blog.

There are no comments on this article.

Add a comment