Subject: bug#41200: Displaying a tooltip with x-show-tip gets very slow as more faces are defined

From: Clément Pit-Claudel <[email-masked]>
Date: Fri, 15 May 2020 15:10:46 -0400

On 15/05/2020 10.03, Stefan Monnier wrote:
>> Indeed, you're completely right; thanks!  Replacing face_alist and
>> Vface_new_frame_defaults with hash tables makes the worst example
>> about 10 times faster, and with that change tooltips now take 30 to
>> 50ms to display instead of 500-600ms in my real-life use case (my
>> usual config).  I have attached a patch.
> 
> Oh, this is great, makes a very noticeable difference.

Thanks for testing!

> The variable's name did not say "alist", so I don't see a need to change
> it from that point of view.  But I think it deserves a "--" since it's
> supposed to be internal.

Ah, that's a good point.  At least, renaming it will make it clear that something changed and make it easy to support older and newer emacsen.

> A quick grep revealed:
> 
>     elpa/packages/context-coloring/fixtures/benchmark/faces.el:  (mapcar #'car face-new-frame-defaults))

AFAICT, this is just a copy of faces.el, used to benchmark syntax highlighting (that is, this code is not run).

>> - command-execute                                                 454  47%
> [...]
>>            - face-set-after-frame-default                         387  40%
>>             - face-spec-recalc                                    374  39%
>>              - make-face-x-resource-internal                      296  30%
>>               - set-face-attributes-from-resources                273  28%
>>                - set-face-attribute-from-resource                 219  22%
> 
> [...]
> 
>> - command-execute                                                 768  80%
> [...]
>>                       - face-set-after-frame-default              674  70%
>>                        - face-spec-recalc                         660  69%
>>                         - face-spec-set-2                         350  36%
>>                          - apply                                  348  36%
>>                           - set-face-attribute                    342  35%
>>                            - internal-set-lisp-face-attribute     342  35%
>>                             - frame-set-background-mode           331  34%
>>                              - face-spec-recalc                   284  29%
>>                               - make-face-x-resource-internal     235  24%
> 
> Both of those profiles suggest that most of the time is still spent in
> `face-spec-recalc`, so it would be worth trying harder to avoid calling
> it or to speed it up somehow (presumably with some better memozing/caching).

Interesting.  I also wonder whether we could fast-track the case where the face spec is a vector full of 'undefined, since that seems to be the common case.