Subject: bug#20887: 'make bootstrap' now verrrry slow due to recent isearch changes

From: Artur Malabarba <[email-masked]>
Date: Thu, 25 Jun 2015 18:32:51 +0100

> However, I think the version you pushed can be further improved.  For
> starters, you don't need to populate the table first, and only then
> use it; you can produce the property value for a character and use it
> in the same call to map-char-table.  For example, the following
> snippet loops only once over the table, and does its job in about 2
> sec:
>
>   (let* ((table (unicode-property-table-internal 'decomposition))
>          (func (char-table-extra-slot table 1)))
>     (map-char-table
>      (lambda (key val)
>        (if (consp key)
>            (message "%s %s" key (funcall func (car key) val table))
>          (message "%s %s" key (funcall func key val table))))
>      table))
>
> All you need is replace the silly 'message' calls with the body of
> your processing code (and handle all the characters in a range of
> codepoints, not just the first one).

The "handle all characters in a range" part is the issue.

For me, the first time that snippet is run it calls the lambda a total
of 101 times (and barely takes an instant).
More importantly, every single time the key is a range, and the value
returned by the `funcall' is actually the decomposition of the *first*
char in that range (not the full range).
For instance, one of the messages I get from your snippet is:
    (64256 . 64383) (compat 102 102)

But if you call (get-char-code-property 64257 'decomposition) (note
the 7) you'll get a decomposition of (compat 102 105).

Maybe I'm missing some simplification here.
I'm aware I could run a loop inside the lambda going from (car key) to
(cdr key), and then do the `(funcall func ...)' on each item in the
range, but I fail to see how that would be faster than running a
second map-char-table. In fact, the number of steps involved is much
larger if you loop:
 - the current version has a map of 100 steps and another of 5721,
 - your proposal would have a map of 100 steps, each containing a loop
of about 120 steps, which totals to over 12000 steps (I counted).

Again, maybe I'm missing something, or maybe looping would be much
faster than that second `map-char-table', but it seems to me like it
would just be doing more work.

> Your code also calls unicode-property-table-internal twice, and the
> above method will solve that as well.

Yes, that was an oversight. My intention was to reuse the `table' var.
I'll fix that.