GNU bug report logs - #41200
Displaying a tooltip with x-show-tip gets very slow as more faces are defined

Previous Next

Package: emacs;

Reported by: Clément Pit-Claudel <cpitclaudel <at> gmail.com>

Date: Tue, 12 May 2020 04:31:01 UTC

Severity: normal

Tags: moreinfo, patch

Merged with 41267

Found in version 26.3

Fixed in version 28.1

Done: Lars Ingebrigtsen <larsi <at> gnus.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 41200 in the body.
You can then email your comments to 41200 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Tue, 12 May 2020 04:31:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Clément Pit-Claudel <cpitclaudel <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Tue, 12 May 2020 04:31:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: bug-gnu-emacs <bug-gnu-emacs <at> gnu.org>
Subject: Displaying a tooltip with x-show-tip gets very slow as more faces are
 defined
Date: Tue, 12 May 2020 00:30:23 -0400
[Message part 1 (text/plain, inline)]
Hi all,

I've recently noticed that opening a tooltip on my machine takes about 0.5s when x-gtk-use-system-tooltips is set to nil.
I bisected my config, and… nothing.  It's not one package: instead, it's an accumulation of small slowdowns.
Is seems that defining a face makes x-show-tip a tiny bit slower, but these effects stack.

Here is a repro:

  (defun my-def-many-faces (nfaces)
    (dotimes (i nfaces)
      (custom-declare-face
       (intern (format "my-face-%d" i))
       '((t)) "A face."
       :group 'basic-faces)))

  (defun my-bench-x-tip (nfaces)
    (setq x-gtk-use-system-tooltips nil)
    (my-def-many-faces nfaces)
    (benchmark-run 1 (x-show-tip "Test" (selected-frame) nil 5 nil nil)))

  (my-bench-x-tip 100) ;; ⇒ (0.035934318 1 0.015908304000000012)
  (my-bench-x-tip 200) ;; ⇒ (0.049593474 1 0.01508625500000002)
  (my-bench-x-tip 300) ;; ⇒ (0.094929297 2 0.03376510099999999)
  (my-bench-x-tip 400) ;; ⇒ (0.094900665 2 0.03254889999999999)
  (my-bench-x-tip 500) ;; ⇒ (0.118183442 2 0.03218763600000002)
  (my-bench-x-tip 600) ;; ⇒ (0.154759438 3 0.04923829399999996)
  (my-bench-x-tip 700) ;; ⇒ (0.183241646 3 0.04901039700000004)
  (my-bench-x-tip 800) ;; ⇒ (0.212218872 3 0.050182316999999976)
  (my-bench-x-tip 900) ;; ⇒ (0.248743542 3 0.04915146899999995)
  (my-bench-x-tip 1000) ;; ⇒ (0.29221963 3 0.04943874300000006)
  (my-bench-x-tip 1100) ;; ⇒ (0.334084605 3 0.05403986499999991)
  (my-bench-x-tip 1200) ;; ⇒ (0.397292289 4 0.06869684599999992)
  (my-bench-x-tip 1300) ;; ⇒ (0.442873256 4 0.06865671799999995)
  (my-bench-x-tip 1400) ;; ⇒ (0.492474982 4 0.06888139900000001)
  (my-bench-x-tip 1500) ;; ⇒ (0.579180262 5 0.08583425400000011)
  (my-bench-x-tip 1600) ;; ⇒ (0.63504114 5 0.08973981699999989)
  (my-bench-x-tip 1700) ;; ⇒ (0.723722857 5 0.09094433899999999)
  (my-bench-x-tip 1800) ;; ⇒ (0.791952279 5 0.08777533800000015)
  (my-bench-x-tip 1900) ;; ⇒ (0.902377982 6 0.10768666300000018)
  (my-bench-x-tip 2000) ;; ⇒ (0.998815784 6 0.11384837999999986)

Be sure to run it in emacs -q, not emacs -Q, because emacs -Q ignores X resources and hence skips the body of make-face-x-resource-internal, which contributes greatly to the issue.
For some reasons the effects are a bit worse in my config — roughly a factor 3 to 5 (I have 600 faces defined, and each tooltip takes .5s to display).  The profiles below suggest that face-spec-set-2 is called in my config, but not in my repro, which could explain part of the difference.

This is what the profile in emacs -q looks like:

- command-execute                                                1742  97%
 - call-interactively                                            1742  97%
  - funcall-interactively                                        1720  96%
   - eval-defun                                                  1711  95%
    - elisp--eval-defun                                          1711  95%
     - eval-region                                               1711  95%
      - let                                                      1711  95%
       - list                                                    1711  95%
        - let                                                    1711  95%
         - x-show-tip                                            1708  95%
          - face-set-after-frame-default                         1708  95%
           - face-spec-recalc                                    1654  92%
            - make-face-x-resource-internal                      1414  78%
             - set-face-attributes-from-resources                1413  78%
              - set-face-attribute-from-resource                 1394  77%
               - face-name                                       1353  75%
                - check-face                                     1348  75%
                   facep                                         1344  75%
            - face-spec-reset-face                                239  13%
             - apply                                              239  13%
                set-face-attribute                                234  13%

And this is what it looks like in my config:

- command-execute                                                1423  87%
 - call-interactively                                            1423  87%
  - apply                                                        1423  87%
   - call-interactively <at> ido-cr+-record-current-command               1423  87%
    - apply                                                      1423  87%
     - #<subr call-interactively>                                1423  87%
      - funcall-interactively                                    1423  87%
       - eval-defun                                              1345  83%
        - apply                                                  1345  83%
         - #<compiled 0x1fa5d1dc39debc9e>                        1345  83%
          - elisp--eval-defun                                    1345  83%
           - eval-region                                         1344  83%
            - apply                                              1344  83%
             - #<lambda -0x120930d847119138>                     1344  83%
              - endless/eval-overlay                             1344  83%
               - apply                                           1343  83%
                - #<subr eval-region>                            1343  83%
                 - my-bench-x-tip                                1343  83%
                  - let                                          1280  79%
                   - list                                        1280  79%
                    - let                                        1280  79%
                     - x-show-tip                                1277  78%
                      - face-set-after-frame-default               1277  78%
                       - face-spec-recalc                        1218  75%
                        - face-spec-set-2                         673  41%
                         - apply                                  672  41%
                          - set-face-attribute                    671  41%
                           - internal-set-lisp-face-attribute                669  41%
                            - frame-set-background-mode                651  40%
                             - face-spec-recalc                   411  25%
                              - make-face-x-resource-internal                352  21%
                               - set-face-attributes-from-resources                350  21%
                                - set-face-attribute-from-resource                343  21%
                                 - face-name                      312  19%
                                  - check-face                    309  19%
                                     facep                        308  19%
                              + face-spec-reset-face                 56   3%
                                face-spec-choose                    1   0%
                              + face-spec-set-2                     1   0%
                             - face-attr-match-p                  235  14%
                                face-attribute                    235  14%
                        - make-face-x-resource-internal                321  19%
                         - set-face-attributes-from-resources                320  19%
                          - set-face-attribute-from-resource                316  19%
                           - face-name                            296  18%
                            - check-face                          294  18%
                               facep                              293  18%
                        - face-spec-reset-face                    223  13%
                         - apply                                  223  13%
                            set-face-attribute                    219  13%
                  + my-def-many-faces                              63   3%
               + cider--make-result-overlay                         1   0%
           + end-of-defun                                           1   0%
       + smex                                                      78   4%
+ ...                                                             188  11%
+ timer-event-handler                                               4   0%
+ redisplay_internal (C function)                                   2   0%
+ flyspell-post-command-hook                                        1   0%


I've attached both profiles.

Clément.

Configured using:
 'configure -C'

Configured features:
XPM JPEG TIFF GIF PNG RSVG CAIRO SOUND GPM DBUS GSETTINGS GLIB NOTIFY
INOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE HARFBUZZ M17N_FLT LIBOTF
ZLIB TOOLKIT_SCROLL_BARS GTK3 X11 XDBE XIM MODULES THREADS LIBSYSTEMD
JSON PDUMPER LCMS2 GMP

Important settings:
  value of $LC_MONETARY: en_DK.UTF-8
  value of $LC_NUMERIC: en_DK.UTF-8
  value of $LC_TIME: en_DK.UTF-8
  value of $LANG: en_US.UTF-8
  value of $XMODIFIERS: @im=ibus
  locale-coding-system: utf-8-unix

Major mode: Fundamental

Minor modes in effect:
  tooltip-mode: t
  global-eldoc-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  buffer-read-only: t
  line-number-mode: t
  transient-mark-mode: t

Load-path shadows:
None found.

Features:
(shadow sort mail-extr emacsbug message rmc puny dired dired-loaddefs
format-spec rfc822 mml easymenu mml-sec password-cache epa derived epg
epg-config gnus-util rmail rmail-loaddefs text-property-search time-date
subr-x seq byte-opt gv bytecomp byte-compile cconv mm-decode mm-bodies
mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader cl-loaddefs
cl-lib sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils
tooltip eldoc electric uniquify ediff-hook vc-hooks lisp-float-type
mwheel term/x-win x-win term/common-win x-dnd tool-bar dnd fontset image
regexp-opt fringe tabulated-list replace newcomment text-mode elisp-mode
lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch
timer select scroll-bar mouse jit-lock font-lock syntax facemenu
font-core term/tty-colors frame minibuffer cl-generic cham georgian
utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean
japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european
ethiopic indian cyrillic chinese composite charscript charprop
case-table epa-hook jka-cmpr-hook help simple abbrev obarray
cl-preloaded nadvice loaddefs button faces cus-face macroexp files
text-properties overlay sha1 md5 base64 format env code-pages mule
custom widget hashtable-print-readable backquote threads dbusbind
inotify lcms2 dynamic-setting system-font-setting font-render-setting
cairo move-toolbar gtk x-toolkit x multi-tty make-network-process emacs)

Memory information:
((conses 16 48162 5363)
 (symbols 48 6344 1)
 (strings 32 15896 1092)
 (string-bytes 1 517314)
 (vectors 16 10213)
 (vector-slots 8 140571 9444)
 (floats 8 19 41)
 (intervals 56 230 7)
 (buffers 992 11))
[tip.emacs-q.prof (text/plain, attachment)]
[tip.personal-config.prof (text/plain, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Tue, 12 May 2020 06:43:02 GMT) Full text and rfc822 format available.

Message #8 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>,
 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Tue, 12 May 2020 08:42:50 +0200
> Is seems that defining a face makes x-show-tip a tiny bit slower, but
> these effects stack.

Please try with 'tooltip-reuse-hidden-frame' non-nil (there's nothing we
can do about a session's first tooltip appearance, though).

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Tue, 12 May 2020 11:31:01 GMT) Full text and rfc822 format available.

Message #11 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: martin rudalics <rudalics <at> gmx.at>, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Tue, 12 May 2020 07:30:01 -0400
On 12/05/2020 02.42, martin rudalics wrote:
>> Is seems that defining a face makes x-show-tip a tiny bit slower, but
>> these effects stack.
> 
> Please try with 'tooltip-reuse-hidden-frame' non-nil (there's nothing we
> can do about a session's first tooltip appearance, though).

I'm not seeing a difference here.  I used this code to test:


(defun my-def-many-faces (nfaces)
  (dotimes (i nfaces)
    (custom-declare-face
     (intern (format "my-face-%d" i))
     '((t)) "A face."
     :group 'basic-faces)))

(defun my-bench-x-tip (nfaces)
  (setq x-gtk-use-system-tooltips nil
        tooltip-reuse-hidden-frame t)
  (my-def-many-faces nfaces)
  (benchmark-run 1 (x-show-tip "Test" (selected-frame) nil 5 nil nil)))





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Tue, 12 May 2020 15:14:02 GMT) Full text and rfc822 format available.

Message #14 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>,
 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Tue, 12 May 2020 17:12:58 +0200
[Message part 1 (text/plain, inline)]
>> Please try with 'tooltip-reuse-hidden-frame' non-nil (there's nothing we
>> can do about a session's first tooltip appearance, though).
>
> I'm not seeing a difference here.  I used this code to test:

Looks like a devastating bug in the GTK builds.  Can you try with the
attached patch?

Thanks, martin
[tooltip-hide.diff (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Tue, 12 May 2020 15:29:02 GMT) Full text and rfc822 format available.

Message #17 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Cc: 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Tue, 12 May 2020 18:27:57 +0300
> Resent-From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
> Original-Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
> Resent-CC: bug-gnu-emacs <at> gnu.org
> Resent-Sender: help-debbugs <at> gnu.org
> From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
> Date: Tue, 12 May 2020 00:30:23 -0400
> 
> 
> [1:text/plain Hide]
> 
> Hi all,
> 
>   (defun my-def-many-faces (nfaces)
>     (dotimes (i nfaces)
>       (custom-declare-face
>        (intern (format "my-face-%d" i))
>        '((t)) "A face."
>        :group 'basic-faces)))
> 
>   (defun my-bench-x-tip (nfaces)
>     (setq x-gtk-use-system-tooltips nil)
>     (my-def-many-faces nfaces)
>     (benchmark-run 1 (x-show-tip "Test" (selected-frame) nil 5 nil nil)))
> 
>   (my-bench-x-tip 100) ;; ⇒ (0.035934318 1 0.015908304000000012)
>   (my-bench-x-tip 200) ;; ⇒ (0.049593474 1 0.01508625500000002)
>   (my-bench-x-tip 300) ;; ⇒ (0.094929297 2 0.03376510099999999)
>   (my-bench-x-tip 400) ;; ⇒ (0.094900665 2 0.03254889999999999)
>   (my-bench-x-tip 500) ;; ⇒ (0.118183442 2 0.03218763600000002)
>   (my-bench-x-tip 600) ;; ⇒ (0.154759438 3 0.04923829399999996)
>   (my-bench-x-tip 700) ;; ⇒ (0.183241646 3 0.04901039700000004)
>   (my-bench-x-tip 800) ;; ⇒ (0.212218872 3 0.050182316999999976)
>   (my-bench-x-tip 900) ;; ⇒ (0.248743542 3 0.04915146899999995)
>   (my-bench-x-tip 1000) ;; ⇒ (0.29221963 3 0.04943874300000006)
>   (my-bench-x-tip 1100) ;; ⇒ (0.334084605 3 0.05403986499999991)
>   (my-bench-x-tip 1200) ;; ⇒ (0.397292289 4 0.06869684599999992)
>   (my-bench-x-tip 1300) ;; ⇒ (0.442873256 4 0.06865671799999995)
>   (my-bench-x-tip 1400) ;; ⇒ (0.492474982 4 0.06888139900000001)
>   (my-bench-x-tip 1500) ;; ⇒ (0.579180262 5 0.08583425400000011)
>   (my-bench-x-tip 1600) ;; ⇒ (0.63504114 5 0.08973981699999989)
>   (my-bench-x-tip 1700) ;; ⇒ (0.723722857 5 0.09094433899999999)
>   (my-bench-x-tip 1800) ;; ⇒ (0.791952279 5 0.08777533800000015)
>   (my-bench-x-tip 1900) ;; ⇒ (0.902377982 6 0.10768666300000018)
>   (my-bench-x-tip 2000) ;; ⇒ (0.998815784 6 0.11384837999999986)
> 
> Be sure to run it in emacs -q, not emacs -Q, because emacs -Q ignores X resources and hence skips the body of make-face-x-resource-internal, which contributes greatly to the issue.
> For some reasons the effects are a bit worse in my config — roughly a factor 3 to 5 (I have 600 faces defined, and each tooltip takes .5s to display).  The profiles below suggest that face-spec-set-2 is called in my config, but not in my repro, which could explain part of the difference.
> 
> This is what the profile in emacs -q looks like:
> 
> - command-execute                                                1742  97%
>  - call-interactively                                            1742  97%
>   - funcall-interactively                                        1720  96%
>    - eval-defun                                                  1711  95%
>     - elisp--eval-defun                                          1711  95%
>      - eval-region                                               1711  95%
>       - let                                                      1711  95%
>        - list                                                    1711  95%
>         - let                                                    1711  95%
>          - x-show-tip                                            1708  95%
>           - face-set-after-frame-default                         1708  95%
>            - face-spec-recalc                                    1654  92%
>             - make-face-x-resource-internal                      1414  78%
>              - set-face-attributes-from-resources                1413  78%
>               - set-face-attribute-from-resource                 1394  77%
>                - face-name                                       1353  75%
>                 - check-face                                     1348  75%
>                    facep                                         1344  75%

If you look at internal-lisp-face-p, which is the workhorse of facep,
you will see that it does the moral equivalent of

  (assq FACE (frame-face-alist))

(The code is actually in a subroutine called by internal-lisp-face-p.)
Which means face-set-after-frame-default, which loops over all of the
faces, runs with O(n²) complexity in the number of faces.

So I think if we want to support such large amounts of faces, we
should not store them in alists, but in a more efficient data
structure.

> Configured using:
>  'configure -C'
> 
> Configured features:
> XPM JPEG TIFF GIF PNG RSVG CAIRO SOUND GPM DBUS GSETTINGS GLIB NOTIFY
> INOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE HARFBUZZ M17N_FLT LIBOTF
> ZLIB TOOLKIT_SCROLL_BARS GTK3 X11 XDBE XIM MODULES THREADS LIBSYSTEMD
> JSON PDUMPER LCMS2 GMP

No Emacs version information?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Tue, 12 May 2020 17:20:02 GMT) Full text and rfc822 format available.

Message #20 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: martin rudalics <rudalics <at> gmx.at>, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Tue, 12 May 2020 13:19:06 -0400
On 12/05/2020 11.12, martin rudalics wrote:
>>> Please try with 'tooltip-reuse-hidden-frame' non-nil (there's nothing we
>>> can do about a session's first tooltip appearance, though).
>>
>> I'm not seeing a difference here.  I used this code to test:
> 
> Looks like a devastating bug in the GTK builds.  Can you try with the
> attached patch?
> 
> Thanks, martin

Indeed, with tooltip-reuse-hidden-frame t and your patch, creating a tooltip is instantaneous (after the first tooltip is created)
The docstring suggests that with this option, results won't always be correct.  Is there a chance that we could rebuild the frame when needed and then make that option the default?






Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Tue, 12 May 2020 17:43:02 GMT) Full text and rfc822 format available.

Message #23 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>,
 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Tue, 12 May 2020 19:42:52 +0200
> Indeed, with tooltip-reuse-hidden-frame t and your patch, creating a
>  tooltip is instantaneous (after the first tooltip is created)

Eli, any problems to fix this in Emacs 27?

> The docstring suggests that with this option, results won't always be
> correct.  Is there a chance that we could rebuild the frame when
> needed and then make that option the default?

It depends on what "when needed" stands for.  Basically, the results may
be incorrect when some sort of face change happens.  But, as I recently
mentioned in another thread, the code not reusing a hidden frame already
fails picking up an internal border face specified via

  (set-face-background 'internal-border "red")

so such annoyances are already present in the default code.

In principle, you can always add or remove some non-position-specifying
alist entry and the tooltip frame will be recreated from scratch.  So if
we can identify the "when needed", it should be easy to add such an
entry and remove it as soon as the next tooltip frame has been created.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Tue, 12 May 2020 17:59:02 GMT) Full text and rfc822 format available.

Message #26 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: martin rudalics <rudalics <at> gmx.at>
Cc: cpitclaudel <at> gmail.com, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Tue, 12 May 2020 20:58:19 +0300
> From: martin rudalics <rudalics <at> gmx.at>
> Date: Tue, 12 May 2020 19:42:52 +0200
> 
>  > Indeed, with tooltip-reuse-hidden-frame t and your patch, creating a
>  >  tooltip is instantaneous (after the first tooltip is created)
> 
> Eli, any problems to fix this in Emacs 27?

No, please go ahead.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Wed, 13 May 2020 02:42:02 GMT) Full text and rfc822 format available.

Message #29 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Tue, 12 May 2020 22:41:24 -0400
[Message part 1 (text/plain, inline)]
On 12/05/2020 11.27, Eli Zaretskii wrote:
> (The code is actually in a subroutine called by internal-lisp-face-p.)
> Which means face-set-after-frame-default, which loops over all of the
> faces, runs with O(n²) complexity in the number of faces.
> 
> So I think if we want to support such large amounts of faces, we
> should not store them in alists, but in a more efficient data
> structure.

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.

I left a few questions in the code; I hope that's OK.  I have a few more questions that are not part of the code:

* I removed the function frame-face-alist and changed the type of the variable face-new-frame-defaults.  Both were documented as internal.  Should I add an ELisp implementation of frame-face-alist for compatibility?  (It wouldn't be a perfect shim, since modifying its return value wouldn't do the same).  For face-new-frame-defaults it's a bit trickier, since the variable now holds a hash table.  Should I change its name to make the change obvious, at least? 
* The name face_hash isn't ideal, since there's already a distinct notion of face hashes (hash codes).  Can you think of a better name? 
* I imagine that this change needs to be advertised somewhere, but I'm not sure where; NEWS?

Lastly, do the following new profiles suggest other opportunities for improvement?

- ...                                                             499  52%
   Automatic GC                                                   499  52%
- command-execute                                                 454  47%
 - call-interactively                                             454  47%
  - funcall-interactively                                         433  45%
   - eval-defun                                                   427  44%
    - elisp--eval-defun                                           427  44%
     - eval-region                                                426  44%
      - my-bench-x-tip                                            426  44%
       - let                                                      406  42%
        - list                                                    406  42%
         - let                                                    406  42%
          - x-show-tip                                            390  40%
           - 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%
                + face-name                                        65   6%
             + face-spec-reset-face                                62   6%
             + face-spec-set-2                                      6   0%
             + face-spec-choose                                     2   0%
            + face-list                                             2   0%
           + frame-windows-min-size                                 1   0%
       + my-def-many-faces                                         20   2%
     + end-of-defun                                                 1   0%
   + execute-extended-command                                       6   0%
  + byte-code                                                      21   2%
+ redisplay_internal (C function)                                   2   0%
  tooltip-hide                                                      1   0%

- command-execute                                                 768  80%
 - call-interactively                                             768  80%
  - apply                                                         768  80%
   - call-interactively <at> ido-cr+-record-current-command                768  80%
    - apply                                                       768  80%
     - #<subr call-interactively>                                 768  80%
      - funcall-interactively                                     768  80%
       - eval-defun                                               715  74%
        - apply                                                   713  74%
         - #<compiled 0x151e3cbebf653c17>                         712  74%
          - elisp--eval-defun                                     712  74%
           - eval-region                                          709  74%
            - apply                                               709  74%
             - #<lambda 0x32ad1cc4311e0c0>                        709  74%
              - endless/eval-overlay                              709  74%
               - apply                                            709  74%
                - #<subr eval-region>                             707  74%
                 - my-bench-x-tip                                 707  74%
                  - let                                           689  72%
                   - list                                         689  72%
                    - let                                         689  72%
                     - x-show-tip                                 676  70%
                      - 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%
                               - set-face-attributes-from-resources                216  22%
                                - set-face-attribute-from-resource                174  18%
                                 - face-name                       36   3%
                                  + check-face                     21   2%
                              + face-spec-reset-face                 40   4%
                              + face-spec-set-2                     4   0%
                             + face-attr-match-p                   24   2%
                               face-spec-choose                     1   0%
                             + face-list                            1   0%
                        - make-face-x-resource-internal                248  25%
                         - set-face-attributes-from-resources                215  22%
                          - set-face-attribute-from-resource                169  17%
                           + face-name                             36   3%
                        + face-spec-reset-face                     54   5%
                        + face-spec-choose                          2   0%
                       + face-list                                  1   0%
                  + my-def-many-faces                              18   1%
           + beginning-of-defun                                     1   0%
             end-of-defun                                           1   0%
        + #<lambda 0x159f62efd027a>                                 2   0%
       + smex                                                      53   5%
- ...                                                             182  19%
   Automatic GC                                                   182  19%
+ redisplay_internal (C function)                                   3   0%

Also, since the GC seems to be a significant part, here's a memory profile:

- command-execute                                         305,314,261  99%
 - call-interactively                                     305,314,261  99%
  - funcall-interactively                                 305,262,257  99%
   - eval-defun                                           303,318,241  98%
    - elisp--eval-defun                                   303,317,185  98%
     - eval-region                                        303,296,332  98%
      - my-bench-x-tip                                    303,295,276  98%
       - let                                              273,049,377  89%
        - list                                            273,049,377  89%
         - let                                            273,049,377  89%
          - x-show-tip                                    177,538,262  57%
           - face-set-after-frame-default                 175,519,190  57%
            - face-spec-recalc                            174,935,046  57%
             - make-face-x-resource-internal              138,435,960  45%
              + set-face-attributes-from-resources        138,407,728  45%
             + face-spec-reset-face                        36,126,838  11%
             + face-spec-choose                                74,360   0%
             + face-spec-set-2                                 21,216   0%
            + face-list                                       554,400   0%
           + frame-windows-min-size                             7,676   0%
           + run-at-time                                        4,352   0%
            setq                                                4,224   0%
          + float-time                                          3,888   0%
       + my-def-many-faces                                 30,245,899   9%
      + internal-macroexpand-for-load                           1,056   0%
     + end-of-defun                                             4,160   0%
     + beginning-of-defun                                       2,112   0%
   + execute-extended-command                               1,944,016   0%
  + byte-code                                                  52,004   0%
+ redisplay_internal (C function)                           1,427,117   0%

> No Emacs version information?

Woops. Sorry! GNU Emacs 28.0.50 (build 10, x86_64-pc-linux-gnu, GTK+ Version 3.22.30, cairo version 1.15.10) of 2020-05-10

Thanks again for the pointers,
Clément.
[0001-Store-frame-faces-in-hash-tables-instead-of-alists.patch (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Wed, 13 May 2020 14:59:02 GMT) Full text and rfc822 format available.

Message #32 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: cpitclaudel <at> gmail.com, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Wed, 13 May 2020 16:58:40 +0200
> No, please go ahead.

Installed meanwhile.

Thanks, martin






Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Wed, 13 May 2020 14:59:02 GMT) Full text and rfc822 format available.

Message #35 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>,
 Eli Zaretskii <eliz <at> gnu.org>
Cc: 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Wed, 13 May 2020 16:58:48 +0200
> 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.

GCC throws the following error here:

  CC       frame.o
In file included from ../../src/lisp.h:954,
                 from ../../src/frame.c:29:
../../src/frame.c: In function ‘make_frame’:
./globals.h:6365:14: error: incompatible type for argument 6 of ‘make_hash_table’
 #define Qnil builtin_lisp_symbol (0)
              ^~~~~~~~~~~~~~~~~~~~~~~
../../src/frame.c:952:57: note: in expansion of macro ‘Qnil’
                         DEFAULT_REHASH_THRESHOLD, Qnil, Qnil));
                                                         ^~~~
In file included from ../../src/conf_post.h:39,
                 from ./config.h:2270,
                 from ../../src/frame.c:20:
../../src/lisp.h:3661:43: note: expected ‘_Bool’ but argument is of type ‘Lisp_Object’ {aka ‘struct Lisp_Object’}
                              Lisp_Object, bool);
                                           ^~~~
make[1]: *** [Makefile:402: frame.o] Fehler 1
make[1]: *** Es wird auf noch nicht beendete Prozesse gewartet....
make[1]: Verzeichnis „/home/martin/emacs-git/release/obj-gtk/src“ wird verlassen
make: *** [Makefile:424: src] Fehler 2

martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Wed, 13 May 2020 15:14:01 GMT) Full text and rfc822 format available.

Message #38 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: martin rudalics <rudalics <at> gmx.at>, Eli Zaretskii <eliz <at> gnu.org>
Cc: 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Wed, 13 May 2020 11:13:27 -0400
[Message part 1 (text/plain, inline)]
On 13/05/2020 10.58, martin rudalics 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.
> 
> GCC throws the following error here:

Woops, thanks. I misread the signature of make_hash_table.  I've attached an updated patch.


[0001-Store-frame-faces-in-hash-tables-instead-of-alists.patch (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Wed, 13 May 2020 17:43:02 GMT) Full text and rfc822 format available.

Message #41 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>,
 Eli Zaretskii <eliz <at> gnu.org>
Cc: 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Wed, 13 May 2020 19:42:52 +0200
> Woops, thanks. I misread the signature of make_hash_table.  I've attached an updated patch.

Thanks.  Builds now and I'm running with it.

martin





Merged 41200 41267. Request was from Eli Zaretskii <eliz <at> gnu.org> to control <at> debbugs.gnu.org. (Thu, 14 May 2020 18:59:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 15 May 2020 11:06:01 GMT) Full text and rfc822 format available.

Message #46 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Cc: 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Fri, 15 May 2020 14:05:24 +0300
> Cc: 41200 <at> debbugs.gnu.org
> From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
> Date: Tue, 12 May 2020 22:41:24 -0400
> 
> > So I think if we want to support such large amounts of faces, we
> > should not store them in alists, but in a more efficient data
> > structure.
> 
> 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.
> 
> I left a few questions in the code; I hope that's OK.  I have a few more questions that are not part of the code:
> 
> * I removed the function frame-face-alist and changed the type of the variable face-new-frame-defaults.  Both were documented as internal.  Should I add an ELisp implementation of frame-face-alist for compatibility?  (It wouldn't be a perfect shim, since modifying its return value wouldn't do the same).  For face-new-frame-defaults it's a bit trickier, since the variable now holds a hash table.  Should I change its name to make the change obvious, at least? 

I'd like to keep the old face-new-frame-defaults and frame-face-alist
for compatibility, but mention in the doc strings that they no longer
return modifiable values, and perhaps deprecate them.

> * The name face_hash isn't ideal, since there's already a distinct notion of face hashes (hash codes).  Can you think of a better name? 

face_hash_table?

> * I imagine that this change needs to be advertised somewhere, but I'm not sure where; NEWS?

Let's think about this after we figured out what changes are needed in
the current functions and variables.

> Lastly, do the following new profiles suggest other opportunities for improvement?

I don't think so, but if the behavior is now linear or sub-linear,
it's the best we can expect, since creating a new frame must walk over
all the faces.

> +  // QUESTION: is this where this should be initialized?

Yes, I think so.  But do we need to do anything when frame is deleted
as well?

> +  fset_face_hash
> +    (f, make_hash_table(hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE,
                         ^^
Our C coding conventions are to leave one space between the function's
name and the opening parenthesis (here and elsewhere in the patch).

> -DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist,
> +// QUESTION: Should I add an ELisp version of frame-face-hash?

You mean, frame-face-alist, right?  Yes, most definitely: I imagine a
lot of code out there uses that, and we wouldn't want to break that.

And I'm not sure we should have it only in Lisp: perhaps we should
maintain the alist as well, and add/remove to/from it when a face is
added or removed in the hash table.  Otherwise this change of
internals will have painful effect on packages that use the current
APIs.

> +	  Lisp_Object lface = HASH_KEY(table, idx);
> +          Lisp_Object face_id = Fget (lface, Qface);
> +          // FIXME why is (get 'tab-line 'face) 0?

A bug, I guess.

> +          if (!FIXNATP (face_id))
> +            // FIXME: I'm not sure what to do in this case

I'm not sure I understand why do you need to look at the existing
face's 'face' property?  The original code didn't.

>    DEFVAR_LISP ("face-new-frame-defaults", Vface_new_frame_defaults,
>      doc: /* List of global face definitions (for internal use only.)  */);
> -  Vface_new_frame_defaults = Qnil;
> +  Vface_new_frame_defaults =
> +    make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE,
> +                     DEFAULT_REHASH_THRESHOLD, Qnil, Qnil);

Why do we need to start with a non-default hash-table?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 15 May 2020 14:05:01 GMT) Full text and rfc822 format available.

Message #49 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 41200 <at> debbugs.gnu.org
Subject: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Fri, 15 May 2020 10:03:44 -0400
> 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.

I'm hoping it can make it into Emacs-27.1, tho it is probably rather
late for such a significant change.

> * I removed the function frame-face-alist and changed the type of the
> variable face-new-frame-defaults.  Both were documented as internal.
> Should I add an ELisp implementation of frame-face-alist for
> compatibility?  (It wouldn't be a perfect shim, since modifying its
> return value wouldn't do the same).  For face-new-frame-defaults it's
> a bit trickier, since the variable now holds a hash table.
> Should I change its name to make the change obvious, at least?

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.

A quick grep revealed:

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

That doesn't seem very serious, but I haven't grep'd the MELPA packages.
I saw no such comparable use of `frame-face-alist` in the wild.

> * The name face_hash isn't ideal, since there's already a distinct
> notion of face hashes (hash codes).  Can you think of a better name?

Yes: it's not a hash, it's a table.

I think the better names refer to the "conceptual" type rather than the
specific implementation type, so I prefer "map" or "table" to "hash",
"alist", "obarray", and whatnot.

> - 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).

The first profile also suggests that we spend too much time in
`make-face-x-resource-internal`.

What caught my eye in the second profile is the fact that we call
`face-spec-recalc` recursively.  I suspect that recursion is not desired.


        Stefan


PS: Maybe another way to speed this up is to do the `face-spec-recalc`
lazily (i.e. only when we encounter the face during redisplay), but
that's probably harder to do and not as good (since it will still be
slow in the case where the frame happens to display hundreds of faces).





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 15 May 2020 14:35:01 GMT) Full text and rfc822 format available.

Message #52 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: cpitclaudel <at> gmail.com, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Fri, 15 May 2020 17:34:22 +0300
> From: Stefan Monnier <monnier <at> iro.umontreal.ca>
> Cc: Eli Zaretskii <eliz <at> gnu.org>, 41200 <at> debbugs.gnu.org
> Date: Fri, 15 May 2020 10:03:44 -0400
> 
> I'm hoping it can make it into Emacs-27.1, tho it is probably rather
> late for such a significant change.

It's too late.  Such a significant change on such a low level is got
to cause some issues, especially as parts of it are
backward-incompatible.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 15 May 2020 15:00:01 GMT) Full text and rfc822 format available.

Message #55 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Fri, 15 May 2020 10:59:36 -0400
[Message part 1 (text/plain, inline)]
Hi Eli,

Thanks a lot for the review.  I have attached an updated version of the patch.

On 15/05/2020 07.05, Eli Zaretskii wrote:
> I'd like to keep the old face-new-frame-defaults and frame-face-alist
> for compatibility, but mention in the doc strings that they no longer
> return modifiable values, and perhaps deprecate them.

Done for frame-face-alist.  But how can one do a read-only variable?  Using the new variable watchers facility?

>> * The name face_hash isn't ideal, since there's already a distinct notion of face hashes (hash codes).  Can you think of a better name? 
> 
> face_hash_table?

Thanks, good idea.  I also liked Stefan's frame_face_map.

>> +  // QUESTION: is this where this should be initialized?
> 
> Yes, I think so.  But do we need to do anything when frame is deleted
> as well?

I'm not sure (I don't know how garbage collection works on the C side in Elisp; I assumed the map would be collected).

>> -DEFUN ("frame-face-alist", Fframe_face_alist, Sframe_face_alist,
>> +// QUESTION: Should I add an ELisp version of frame-face-hash?
> 
> You mean, frame-face-alist, right?  Yes, most definitely: I imagine a
> lot of code out there uses that, and we wouldn't want to break that.

Done.

I looked around, but I didn't find many uses at all (for example, there are none in ELPA).  I think this is likely because the function is documented as "For internal use only."

There are no uses of face-new-frame-defaults in ELPA either; online, I found many copies of lisp-mode and emacs-lisp-mode, which refer it, and a few functions derived from edebug-eval-defun, which references it.

> And I'm not sure we should have it only in Lisp: perhaps we should
> maintain the alist as well, and add/remove to/from it when a face is
> added or removed in the hash table.  Otherwise this change of
> internals will have painful effect on packages that use the current
> APIs.

frame-face-alist is likely less crucial than face-new-frame-defaults, because it was already a function, so the return value has to be mutated in place to modify it (it couldn't be directly assigned).  For both of these, however, how would we ensure that the alist remains in sync with the hashmap (that is, how do we catch modifications?)

>> +	  Lisp_Object lface = HASH_KEY(table, idx);
>> +          Lisp_Object face_id = Fget (lface, Qface);
>> +          // FIXME why is (get 'tab-line 'face) 0?
> 
> A bug, I guess.

As far as I can see, these IDs are assigned by Finternal_make_lisp_face, and I *think* it is never called for tab-line?  Should I make sure that it is? If so, where from?

> 
>> +          if (!FIXNATP (face_id))
>> +            // FIXME: I'm not sure what to do in this case
> 
> I'm not sure I understand why do you need to look at the existing
> face's 'face' property?  The original code didn't.

The original code iterated over face-frame-alist in the order in which entries were added to it.  If I understand correctly, iteration order isn't guaranteed on hash tables (is it?), so I had to find a different source of truth for these.

> 
>>    DEFVAR_LISP ("face-new-frame-defaults", Vface_new_frame_defaults,
>>      doc: /* List of global face definitions (for internal use only.)  */);
>> -  Vface_new_frame_defaults = Qnil;
>> +  Vface_new_frame_defaults =
>> +    make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE,
>> +                     DEFAULT_REHASH_THRESHOLD, Qnil, Qnil);
> 
> Why do we need to start with a non-default hash-table?

I wanted to use `eq' instead of `eql' as the test (is that what you were asking?)

[0001-Store-frame-faces-in-hash-tables-instead-of-alists.patch (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 15 May 2020 15:19:02 GMT) Full text and rfc822 format available.

Message #58 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Cc: 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Fri, 15 May 2020 18:17:53 +0300
> Cc: 41200 <at> debbugs.gnu.org
> From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
> Date: Fri, 15 May 2020 10:59:36 -0400
> 
> > I'd like to keep the old face-new-frame-defaults and frame-face-alist
> > for compatibility, but mention in the doc strings that they no longer
> > return modifiable values, and perhaps deprecate them.
> 
> Done for frame-face-alist.  But how can one do a read-only variable?  Using the new variable watchers facility?

At the very least mention in the doc string.  I don't think using
watchable symbols is needed here, it sounds gross.  If there's an
outcry that this breaks too much code out there, we could revisit
this.

> >> * The name face_hash isn't ideal, since there's already a distinct notion of face hashes (hash codes).  Can you think of a better name? 
> > 
> > face_hash_table?
> 
> Thanks, good idea.  I also liked Stefan's frame_face_map.

"Map" is too general, IMO, it doesn't tell enough about the kind of
object it is.

> >> +  // QUESTION: is this where this should be initialized?
> > 
> > Yes, I think so.  But do we need to do anything when frame is deleted
> > as well?
> 
> I'm not sure (I don't know how garbage collection works on the C side in Elisp; I assumed the map would be collected).

I guess so.

> > You mean, frame-face-alist, right?  Yes, most definitely: I imagine a
> > lot of code out there uses that, and we wouldn't want to break that.
> 
> Done.
> 
> I looked around, but I didn't find many uses at all (for example, there are none in ELPA).  I think this is likely because the function is documented as "For internal use only."
> 
> There are no uses of face-new-frame-defaults in ELPA either; online, I found many copies of lisp-mode and emacs-lisp-mode, which refer it, and a few functions derived from edebug-eval-defun, which references it.

That means we will probably be able to remove it earlier than I
feared.

> > And I'm not sure we should have it only in Lisp: perhaps we should
> > maintain the alist as well, and add/remove to/from it when a face is
> > added or removed in the hash table.  Otherwise this change of
> > internals will have painful effect on packages that use the current
> > APIs.
> 
> frame-face-alist is likely less crucial than face-new-frame-defaults, because it was already a function, so the return value has to be mutated in place to modify it (it couldn't be directly assigned).  For both of these, however, how would we ensure that the alist remains in sync with the hashmap (that is, how do we catch modifications?)

I thought about updating the alist when the hash-table is modified.
Since you always know whether the face is already in the hash-table,
you don't need to scan the alist looking for it.

I'd really like to know that no one is using these before we make the
final decision about this.

> >> +	  Lisp_Object lface = HASH_KEY(table, idx);
> >> +          Lisp_Object face_id = Fget (lface, Qface);
> >> +          // FIXME why is (get 'tab-line 'face) 0?
> > 
> > A bug, I guess.
> 
> As far as I can see, these IDs are assigned by Finternal_make_lisp_face, and I *think* it is never called for tab-line?

Most probably.

> Should I make sure that it is?

Yes, I think so.

> If so, where from?

I think the problem is that tab-line is declared a basic face, but its
defface form is not in faces.el.

> >> +          if (!FIXNATP (face_id))
> >> +            // FIXME: I'm not sure what to do in this case
> > 
> > I'm not sure I understand why do you need to look at the existing
> > face's 'face' property?  The original code didn't.
> 
> The original code iterated over face-frame-alist in the order in which entries were added to it.  If I understand correctly, iteration order isn't guaranteed on hash tables (is it?), so I had to find a different source of truth for these.

Maybe we should store the ID with the face?  I think we wanted to get
rid of the 'face' property of the faces at some point.

> >>    DEFVAR_LISP ("face-new-frame-defaults", Vface_new_frame_defaults,
> >>      doc: /* List of global face definitions (for internal use only.)  */);
> >> -  Vface_new_frame_defaults = Qnil;
> >> +  Vface_new_frame_defaults =
> >> +    make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE,
> >> +                     DEFAULT_REHASH_THRESHOLD, Qnil, Qnil);
> > 
> > Why do we need to start with a non-default hash-table?
> 
> I wanted to use `eq' instead of `eql' as the test (is that what you were asking?)

No, I was asking why not start with it as nil and actually make a
hash-table when we first need it.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 15 May 2020 15:34:01 GMT) Full text and rfc822 format available.

Message #61 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Noam Postavsky <npostavs <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Clément Pit-Claudel <cpitclaudel <at> gmail.com>,
 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Fri, 15 May 2020 11:33:40 -0400
Eli Zaretskii <eliz <at> gnu.org> writes:

>> Done for frame-face-alist.  But how can one do a read-only variable?
>> Using the new variable watchers facility?
>
> At the very least mention in the doc string.  I don't think using
> watchable symbols is needed here, it sounds gross.  If there's an
> outcry that this breaks too much code out there, we could revisit
> this.

You can use make_symbol_constant to make a variable read-only.  You
could also simulate it with a variable watcher that signals an error,
but there's no sense in doing that when make_symbol_constant exists.

Neither of these makes the list object itself read-only though.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 15 May 2020 16:24:02 GMT) Full text and rfc822 format available.

Message #64 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 41200 <at> debbugs.gnu.org, Anders Lindgren <andlind <at> gmail.com>
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Fri, 15 May 2020 12:22:53 -0400
On 15/05/2020 11.17, Eli Zaretskii wrote:
>>>> * The name face_hash isn't ideal, since there's already a distinct notion of face hashes (hash codes).  Can you think of a better name? 
>>>
>>> face_hash_table?
>>
>> Thanks, good idea.  I also liked Stefan's frame_face_map.
> 
> "Map" is too general, IMO, it doesn't tell enough about the kind of
> object it is.

Got it.  Is face_table better? (that was Stefan's other suggestion)
 
>>> And I'm not sure we should have it only in Lisp: perhaps we should
>>> maintain the alist as well, and add/remove to/from it when a face is
>>> added or removed in the hash table.  Otherwise this change of
>>> internals will have painful effect on packages that use the current
>>> APIs.
>>
>> frame-face-alist is likely less crucial than face-new-frame-defaults, because it was already a function, so the return value has to be mutated in place to modify it (it couldn't be directly assigned).  For both of these, however, how would we ensure that the alist remains in sync with the hashmap (that is, how do we catch modifications?)
> 
> I thought about updating the alist when the hash-table is modified.
> Since you always know whether the face is already in the hash-table,
> you don't need to scan the alist looking for it.

Would that be done in C, or in any place where frame-new-face-defaults is modified?  (for example, edebug changes face-new-frame-defaults in one place; if we keep the alist in addition to the hash table, would it modify both or would there be a C mechanism that mirrors hash-table modifications to the alist?)

> I'd really like to know that no one is using these before we make the
> final decision about this.

That's a fair point.  While I couldn't find uses of frame-face-alist, there are a few uses of face-new-frame-defaults-alist: https://github.com/pestctrl/emacs-config/commit/31d6bff97dacf60f71066902a23d37e59b4c1288 is from someone who uses that to speed up temporary frame creation(!), https://github.com/Lindydancer/face-explorer/blob/13bd4553bc4b09215a04d0267be1cb4ed834775c/test/face-explorer-test-faces.el is from Anders Lindgren (in CC; hi Andres! We're considering replacing face-new-frame-defaults-alist with a hash table, would that be an issue?), who uses it to remove a face, and https://github.com/Wilfred/elisp-fu/blob/92c491584f466ee729ea1b328234636e65e2c665/elisp-fu.el includes code that's the same as in eval-defun.

I have a variant of the patch that keeps the alist variable, but I fear that it's worse than removing it: since changes to the alist won't be propagated to the hash table, it might be better to error out with a compilation error?

Btw, I have one more question: some callers of face-list seems to rely on the order of faces added to it, so it would be better to preserve that order.  Since hash-tables are not necessarily ordered, should I sort faces by face-id before returning them? 

>> If so, where from?
> 
> I think the problem is that tab-line is declared a basic face, but its
> defface form is not in faces.el.

Ah, good catch.  Current there's a defface for tab-bar in lisp/tab-bar, and since that's preloaded it works, but the defface for tab-line is in lisp/tab-line.el and so isn't preloaded.
Should I move both to faces.el?
 
>>>> +          if (!FIXNATP (face_id))
>>>> +            // FIXME: I'm not sure what to do in this case
>>>
>>> I'm not sure I understand why do you need to look at the existing
>>> face's 'face' property?  The original code didn't.
>>
>> The original code iterated over face-frame-alist in the order in which entries were added to it.  If I understand correctly, iteration order isn't guaranteed on hash tables (is it?), so I had to find a different source of truth for these.
> 
> Maybe we should store the ID with the face?  I think we wanted to get
> rid of the 'face' property of the faces at some point.

Sounds reasonable; but where would we store it?  Right now faces are just symbols, right?

> No, I was asking why not start with it as nil and actually make a
> hash-table when we first need it.

Oh, I thought it would be simpler to always have a hash table instead of having to sanity check every time.

Thanks a lot,
Clément.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 15 May 2020 17:29:01 GMT) Full text and rfc822 format available.

Message #67 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Cc: 41200 <at> debbugs.gnu.org, andlind <at> gmail.com
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Fri, 15 May 2020 20:28:11 +0300
> Cc: 41200 <at> debbugs.gnu.org, Anders Lindgren <andlind <at> gmail.com>
> From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
> Date: Fri, 15 May 2020 12:22:53 -0400
> 
> >>> face_hash_table?
> >>
> >> Thanks, good idea.  I also liked Stefan's frame_face_map.
> > 
> > "Map" is too general, IMO, it doesn't tell enough about the kind of
> > object it is.
> 
> Got it.  Is face_table better? (that was Stefan's other suggestion)

Is anything wrong with face_hash_table?

> > I thought about updating the alist when the hash-table is modified.
> > Since you always know whether the face is already in the hash-table,
> > you don't need to scan the alist looking for it.
> 
> Would that be done in C, or in any place where frame-new-face-defaults is modified?  (for example, edebug changes face-new-frame-defaults in one place; if we keep the alist in addition to the hash table, would it modify both or would there be a C mechanism that mirrors hash-table modifications to the alist?)

The latter was what I had in mind.

> I have a variant of the patch that keeps the alist variable, but I fear that it's worse than removing it: since changes to the alist won't be propagated to the hash table, it might be better to error out with a compilation error?

Not sure yet, it depends on how this is used.

> Btw, I have one more question: some callers of face-list seems to rely on the order of faces added to it, so it would be better to preserve that order.  Since hash-tables are not necessarily ordered, should I sort faces by face-id before returning them? 

Yes, I think so.

> > I think the problem is that tab-line is declared a basic face, but its
> > defface form is not in faces.el.
> 
> Ah, good catch.  Current there's a defface for tab-bar in lisp/tab-bar, and since that's preloaded it works, but the defface for tab-line is in lisp/tab-line.el and so isn't preloaded.
> Should I move both to faces.el?

Yes, I think so.

> >>> I'm not sure I understand why do you need to look at the existing
> >>> face's 'face' property?  The original code didn't.
> >>
> >> The original code iterated over face-frame-alist in the order in which entries were added to it.  If I understand correctly, iteration order isn't guaranteed on hash tables (is it?), so I had to find a different source of truth for these.
> > 
> > Maybe we should store the ID with the face?  I think we wanted to get
> > rid of the 'face' property of the faces at some point.
> 
> Sounds reasonable; but where would we store it?  Right now faces are just symbols, right?

Don't hash-tables allow us to store more than one item in each slot?

> > No, I was asking why not start with it as nil and actually make a
> > hash-table when we first need it.
> 
> Oh, I thought it would be simpler to always have a hash table instead of having to sanity check every time.

What is the default size of a hash-table?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 15 May 2020 18:51:01 GMT) Full text and rfc822 format available.

Message #70 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 41200 <at> debbugs.gnu.org, Juri Linkov <juri <at> linkov.net>
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Fri, 15 May 2020 14:50:17 -0400
[Message part 1 (text/plain, inline)]
On 15/05/2020 13.28, Eli Zaretskii wrote:
>> Cc: 41200 <at> debbugs.gnu.org, Anders Lindgren <andlind <at> gmail.com>
>> From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
>> Date: Fri, 15 May 2020 12:22:53 -0400
>>
>>>>> face_hash_table?
>>>>
>>>> Thanks, good idea.  I also liked Stefan's frame_face_map.
>>>
>>> "Map" is too general, IMO, it doesn't tell enough about the kind of
>>> object it is.
>>
>> Got it.  Is face_table better? (that was Stefan's other suggestion)
> 
> Is anything wrong with face_hash_table?

Nope; I've attached a new patch.

>> Btw, I have one more question: some callers of face-list seems to rely on the order of faces added to it, so it would be better to preserve that order.  Since hash-tables are not necessarily ordered, should I sort faces by face-id before returning them? 

Done in the attached patch as well.

>>> I think the problem is that tab-line is declared a basic face, but its
>>> defface form is not in faces.el.
>>
>> Ah, good catch.  Current there's a defface for tab-bar in lisp/tab-bar, and since that's preloaded it works, but the defface for tab-line is in lisp/tab-line.el and so isn't preloaded.
>> Should I move both to faces.el?
>>
> Yes, I think so.

Thanks.  I will ask Juri to confirm before moving them, because I realize now that they have a custom group.
Juri (CC'd; hi Juri!), was there a reason to make tab-bar and tab-line basic faces?  I see they are both in their own files and groups, instead of being in faces.el.

>>>>> I'm not sure I understand why do you need to look at the existing
>>>>> face's 'face' property?  The original code didn't.
>>>>
>>>> The original code iterated over face-frame-alist in the order in which entries were added to it.  If I understand correctly, iteration order isn't guaranteed on hash tables (is it?), so I had to find a different source of truth for these.
>>>
>>> Maybe we should store the ID with the face?  I think we wanted to get
>>> rid of the 'face' property of the faces at some point.
>>
>> Sounds reasonable; but where would we store it?  Right now faces are just symbols, right?
> 
> Don't hash-tables allow us to store more than one item in each slot?

They do, so I can certainly store (face-id . face-vector) in the hash table.  Done in the attached patch.  I only do this in Vface_new_frame_defaults, not in frame->face_hash_table.

>>> No, I was asking why not start with it as nil and actually make a
>>> hash-table when we first need it.
>>
>> Oh, I thought it would be simpler to always have a hash table instead of having to sanity check every time.
> 
> What is the default size of a hash-table?

65 entries, I think.

[0001-Store-frame-faces-in-hash-tables-instead-of-alists.patch (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 15 May 2020 19:07:01 GMT) Full text and rfc822 format available.

Message #73 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Cc: 41200 <at> debbugs.gnu.org, juri <at> linkov.net
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Fri, 15 May 2020 22:05:53 +0300
> Cc: 41200 <at> debbugs.gnu.org, Juri Linkov <juri <at> linkov.net>
> From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
> Date: Fri, 15 May 2020 14:50:17 -0400
> 
> >>> No, I was asking why not start with it as nil and actually make a
> >>> hash-table when we first need it.
> >>
> >> Oh, I thought it would be simpler to always have a hash table instead of having to sanity check every time.
> > 
> > What is the default size of a hash-table?
> 
> 65 entries, I think.

The number of basic faces is just 18.  Is 65 a good initial size for
that?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 15 May 2020 19:11:01 GMT) Full text and rfc822 format available.

Message #76 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
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.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 15 May 2020 19:24:02 GMT) Full text and rfc822 format available.

Message #79 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 41200 <at> debbugs.gnu.org, juri <at> linkov.net
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Fri, 15 May 2020 15:23:00 -0400
On 15/05/2020 15.05, Eli Zaretskii wrote:
>> Cc: 41200 <at> debbugs.gnu.org, Juri Linkov <juri <at> linkov.net>
>> From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
>> Date: Fri, 15 May 2020 14:50:17 -0400
>>
>>>>> No, I was asking why not start with it as nil and actually make a
>>>>> hash-table when we first need it.
>>>>
>>>> Oh, I thought it would be simpler to always have a hash table instead of having to sanity check every time.
>>>
>>> What is the default size of a hash-table?
>>
>> 65 entries, I think.
> 
> The number of basic faces is just 18.  Is 65 a good initial size for
> that?

I think that map stores more than just the basic faces: in fact, $ emacs -Q --batch --eval '(print (length (frame-face-alist)))' prints 100, so maybe I should even make the map larger by default?

Clément.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 15 May 2020 19:39:02 GMT) Full text and rfc822 format available.

Message #82 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Cc: 41200 <at> debbugs.gnu.org, juri <at> linkov.net
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Fri, 15 May 2020 22:38:21 +0300
> Cc: 41200 <at> debbugs.gnu.org, juri <at> linkov.net
> From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
> Date: Fri, 15 May 2020 15:23:00 -0400
> 
> >>> What is the default size of a hash-table?
> >>
> >> 65 entries, I think.
> > 
> > The number of basic faces is just 18.  Is 65 a good initial size for
> > that?
> 
> I think that map stores more than just the basic faces: in fact, $ emacs -Q --batch --eval '(print (length (frame-face-alist)))' prints 100, so maybe I should even make the map larger by default?

We are miscommunicating.  I was talking about the size before loadup,
i.e. in temacs when it starts up.  Later, when we load preloaded
packages, the size should grow, but the hash-table takes care of that
by itself, doesn't it?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 15 May 2020 19:53:01 GMT) Full text and rfc822 format available.

Message #85 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 41200 <at> debbugs.gnu.org, juri <at> linkov.net
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Fri, 15 May 2020 15:52:26 -0400
[Message part 1 (text/plain, inline)]
On 15/05/2020 15.38, Eli Zaretskii wrote:
>> Cc: 41200 <at> debbugs.gnu.org, juri <at> linkov.net
>> From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
>> Date: Fri, 15 May 2020 15:23:00 -0400
>>
>>>>> What is the default size of a hash-table?
>>>>
>>>> 65 entries, I think.
>>>
>>> The number of basic faces is just 18.  Is 65 a good initial size for
>>> that?
>>
>> I think that map stores more than just the basic faces: in fact, $ emacs -Q --batch --eval '(print (length (frame-face-alist)))' prints 100, so maybe I should even make the map larger by default?
> 
> We are miscommunicating.  I was talking about the size before loadup,
> i.e. in temacs when it starts up.

Ah, yes.  I think I mas mixing up the face_hash_table of each frame and Vface_new_frame_defaults.  Attached is a patch that makes Vface_new_frame_defaults 33-entries large.  Should I also change the default size for face_hash_table in struct frame?

> Later, when we load preloaded packages, the size should grow, but the
> hash-table takes care of that by itself, doesn't it?
Yes, definitely.

[0001-Store-frame-faces-in-hash-tables-instead-of-alists.patch (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 15 May 2020 21:24:02 GMT) Full text and rfc822 format available.

Message #88 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Fri, 15 May 2020 17:23:17 -0400
> 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.

I was thinking also of the case where no face specs have changed and the
frame is "normal" (same frame properties as others, basically) so we
could re-use the faces from another frame.

[ After all, my Emacs sessions typically have dozens of frames, and only
  one of them (a minibuffer-only frame) has faces setup differently
  because it's configured to use a slightly larger font.  ]


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Sat, 16 May 2020 08:46:02 GMT) Full text and rfc822 format available.

Message #91 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>,
 Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Cc: 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Sat, 16 May 2020 10:45:25 +0200
> I was thinking also of the case where no face specs have changed and the
> frame is "normal" (same frame properties as others, basically) so we
> could re-use the faces from another frame.

That's my hope as well.  For years now I'm making frames temporarily
invisible in order to avoid setting up faces for a new frame.

> [ After all, my Emacs sessions typically have dozens of frames, and only
>    one of them (a minibuffer-only frame) has faces setup differently
>    because it's configured to use a slightly larger font.  ]

In my setup the minibuffer-only frame doesn't even do that.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Sat, 16 May 2020 23:25:01 GMT) Full text and rfc822 format available.

Message #94 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Sun, 17 May 2020 02:03:04 +0300
>>>> I think the problem is that tab-line is declared a basic face, but its
>>>> defface form is not in faces.el.
>>>
>>> Ah, good catch.  Current there's a defface for tab-bar in lisp/tab-bar, and since that's preloaded it works, but the defface for tab-line is in lisp/tab-line.el and so isn't preloaded.
>>> Should I move both to faces.el?
>>>
>> Yes, I think so.
>
> Thanks.  I will ask Juri to confirm before moving them, because I realize now that they have a custom group.
> Juri (CC'd; hi Juri!), was there a reason to make tab-bar and tab-line basic faces?  I see they are both in their own files and groups, instead of being in faces.el.

Actually, no reason other than consistency of faces belonging to the
same file where they are used.  But if it will fix the technical problem,
please move them to faces.el, especially given the fact that their
counterpart tool-bar face is already defined in faces.el.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Sat, 16 May 2020 23:44:01 GMT) Full text and rfc822 format available.

Message #97 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: Juri Linkov <juri <at> linkov.net>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Sat, 16 May 2020 19:43:07 -0400
[Message part 1 (text/plain, inline)]
On 16/05/2020 19.03, Juri Linkov wrote:
>>>>> I think the problem is that tab-line is declared a basic face, but its
>>>>> defface form is not in faces.el.
>>>>
>>>> Ah, good catch.  Current there's a defface for tab-bar in lisp/tab-bar, and since that's preloaded it works, but the defface for tab-line is in lisp/tab-line.el and so isn't preloaded.
>>>> Should I move both to faces.el?
>>>>
>>> Yes, I think so.
>>
>> Thanks.  I will ask Juri to confirm before moving them, because I realize now that they have a custom group.
>> Juri (CC'd; hi Juri!), was there a reason to make tab-bar and tab-line basic faces?  I see they are both in their own files and groups, instead of being in faces.el.
> 
> Actually, no reason other than consistency of faces belonging to the
> same file where they are used.  But if it will fix the technical problem,
> please move them to faces.el, especially given the fact that their
> counterpart tool-bar face is already defined in faces.el.

Thanks a lot.  The attached patch does that.
[0001-Move-tab-bar-and-tab-line-to-faces.el-part-of-bug-41.patch (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Sun, 17 May 2020 22:15:02 GMT) Full text and rfc822 format available.

Message #100 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Mon, 18 May 2020 00:59:20 +0300
> +  :group 'basic-faces)
> +
> +  :group 'basic-faces)
>
> -  :group 'tab-bar-faces)
> -
> -  :group 'tab-line-faces)

Could these faces belong to both groups?

  :group 'basic-faces
  :group 'tab-bar-faces




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Mon, 18 May 2020 01:20:02 GMT) Full text and rfc822 format available.

Message #103 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: Juri Linkov <juri <at> linkov.net>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Sun, 17 May 2020 21:19:50 -0400
On 17/05/2020 17.59, Juri Linkov wrote:
>> +  :group 'basic-faces)
>> +
>> +  :group 'basic-faces)
>>
>> -  :group 'tab-bar-faces)
>> -
>> -  :group 'tab-line-faces)
> 
> Could these faces belong to both groups?
> 
>   :group 'basic-faces
>   :group 'tab-bar-faces

Yup, but that won't work well if the face is customized before the group is defined, right? Maybe the trick would be to add the group to the face when tab-bar.el and tab-bar-line.el are loaded?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Tue, 19 May 2020 22:26:03 GMT) Full text and rfc822 format available.

Message #106 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Wed, 20 May 2020 00:48:55 +0300
>>> +  :group 'basic-faces)
>>> +
>>> +  :group 'basic-faces)
>>>
>>> -  :group 'tab-bar-faces)
>>> -
>>> -  :group 'tab-line-faces)
>> 
>> Could these faces belong to both groups?
>> 
>>   :group 'basic-faces
>>   :group 'tab-bar-faces
>
> Yup, but that won't work well if the face is customized before the
> group is defined, right?  Maybe the trick would be to add the group to
> the face when tab-bar.el and tab-line.el are loaded?

Actually since tab-bar.el is pre-loaded this problem exists only for
tab-line.el.

Then adding something like

  (nconc (get 'tab-line-faces 'custom-group) '((tab-line custom-face) ...))

to tab-line.el will add faces when tab-line.el are loaded.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Sat, 23 May 2020 08:12:02 GMT) Full text and rfc822 format available.

Message #109 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>
Cc: cpitclaudel <at> gmail.com, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Sat, 23 May 2020 11:11:46 +0300
> From: Juri Linkov <juri <at> linkov.net>
> Cc: Eli Zaretskii <eliz <at> gnu.org>,  41200 <at> debbugs.gnu.org
> Date: Wed, 20 May 2020 00:48:55 +0300
> 
> >>> +  :group 'basic-faces)
> >>> +
> >>> +  :group 'basic-faces)
> >>>
> >>> -  :group 'tab-bar-faces)
> >>> -
> >>> -  :group 'tab-line-faces)
> >> 
> >> Could these faces belong to both groups?
> >> 
> >>   :group 'basic-faces
> >>   :group 'tab-bar-faces
> >
> > Yup, but that won't work well if the face is customized before the
> > group is defined, right?  Maybe the trick would be to add the group to
> > the face when tab-bar.el and tab-line.el are loaded?
> 
> Actually since tab-bar.el is pre-loaded this problem exists only for
> tab-line.el.
> 
> Then adding something like
> 
>   (nconc (get 'tab-line-faces 'custom-group) '((tab-line custom-face) ...))
> 
> to tab-line.el will add faces when tab-line.el are loaded.

Could you guys please finalize these issues?  I'd like to install
these changes on master, for which I'd need a patch that covers both
the changes in the face storage and the fix for the tab-line face.

Actually, the problem with the tab-line face will probably need to be
fixed on emacs-27.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Sat, 23 May 2020 22:57:02 GMT) Full text and rfc822 format available.

Message #112 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: cpitclaudel <at> gmail.com, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Sun, 24 May 2020 01:47:28 +0300
>> >> Could these faces belong to both groups?
>> >> 
>> >>   :group 'basic-faces
>> >>   :group 'tab-bar-faces
>> >
>> > Yup, but that won't work well if the face is customized before the
>> > group is defined, right?  Maybe the trick would be to add the group to
>> > the face when tab-bar.el and tab-line.el are loaded?
>> 
>> Actually since tab-bar.el is pre-loaded this problem exists only for
>> tab-line.el.
>> 
>> Then adding something like
>> 
>>   (nconc (get 'tab-line-faces 'custom-group) '((tab-line custom-face) ...))
>> 
>> to tab-line.el will add faces when tab-line.el are loaded.
>
> Could you guys please finalize these issues?  I'd like to install
> these changes on master, for which I'd need a patch that covers both
> the changes in the face storage and the fix for the tab-line face.
>
> Actually, the problem with the tab-line face will probably need to be
> fixed on emacs-27.

I don't recommend using the trick with nconc in emacs-27.  It would be
less risky if Clément will just move tab faces to faces.el in emacs-27.

Or may I suggest to preload tab-line.el in emacs-27?
That will solve the problem as well.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Sun, 24 May 2020 02:34:02 GMT) Full text and rfc822 format available.

Message #115 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>
Cc: cpitclaudel <at> gmail.com, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Sun, 24 May 2020 05:33:03 +0300
> From: Juri Linkov <juri <at> linkov.net>
> Cc: cpitclaudel <at> gmail.com,  41200 <at> debbugs.gnu.org
> Date: Sun, 24 May 2020 01:47:28 +0300
> 
> > Actually, the problem with the tab-line face will probably need to be
> > fixed on emacs-27.
> 
> I don't recommend using the trick with nconc in emacs-27.  It would be
> less risky if Clément will just move tab faces to faces.el in emacs-27.

Agreed.

> Or may I suggest to preload tab-line.el in emacs-27?

Doesn't sound justified to me.  I don't expect this feature to be so
popular as to always have it available.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Sun, 24 May 2020 22:11:02 GMT) Full text and rfc822 format available.

Message #118 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: cpitclaudel <at> gmail.com, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Mon, 25 May 2020 00:50:14 +0300
>> Or may I suggest to preload tab-line.el in emacs-27?
>
> Doesn't sound justified to me.  I don't expect this feature to be so
> popular as to always have it available.

Agreed, better to move deffaces to faces.el.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Mon, 08 Jun 2020 00:24:02 GMT) Full text and rfc822 format available.

Message #121 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: cpitclaudel <at> gmail.com, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Mon, 08 Jun 2020 03:21:58 +0300
>> >>> +  :group 'basic-faces)
>> >>> +  :group 'basic-faces)
>> >>>
>> >>> -  :group 'tab-bar-faces)
>> >>> -  :group 'tab-line-faces)
>> >>
>> >> Could these faces belong to both groups?
>> >>
>> >>   :group 'basic-faces
>> >>   :group 'tab-bar-faces
>> >
>> > Yup, but that won't work well if the face is customized before the
>> > group is defined, right?  Maybe the trick would be to add the group to
>> > the face when tab-bar.el and tab-line.el are loaded?
>>
>> Actually since tab-bar.el is pre-loaded this problem exists only for
>> tab-line.el.
>>
>> Then adding something like
>>
>>   (nconc (get 'tab-line-faces 'custom-group) '((tab-line custom-face) ...))
>>
>> to tab-line.el will add faces when tab-line.el are loaded.
>
> Could you guys please finalize these issues?  I'd like to install
> these changes on master, for which I'd need a patch that covers both
> the changes in the face storage and the fix for the tab-line face.
>
> Actually, the problem with the tab-line face will probably need to be
> fixed on emacs-27.

I never used the second argument MEMBERS of 'defgroup', but it's exactly
what is needed.  Now the problem with the tab-line face is fixed on emacs-27
in commit 6eb18a950d.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Sat, 20 Jun 2020 07:48:01 GMT) Full text and rfc822 format available.

Message #124 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>, Clément Pit-Claudel
 <cpitclaudel <at> gmail.com>
Cc: 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Sat, 20 Jun 2020 10:47:29 +0300
> From: Juri Linkov <juri <at> linkov.net>
> Cc: cpitclaudel <at> gmail.com,  41200 <at> debbugs.gnu.org
> Date: Mon, 08 Jun 2020 03:21:58 +0300
> 
> > Could you guys please finalize these issues?  I'd like to install
> > these changes on master, for which I'd need a patch that covers both
> > the changes in the face storage and the fix for the tab-line face.
> >
> > Actually, the problem with the tab-line face will probably need to be
> > fixed on emacs-27.
> 
> I never used the second argument MEMBERS of 'defgroup', but it's exactly
> what is needed.  Now the problem with the tab-line face is fixed on emacs-27
> in commit 6eb18a950d.

Thanks.

Clément, would you like to rebase your patch on the current master and
resubmit?  I think we are ready for installing it.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Sat, 20 Jun 2020 16:56:02 GMT) Full text and rfc822 format available.

Message #127 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>, Juri Linkov <juri <at> linkov.net>
Cc: 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Sat, 20 Jun 2020 12:55:18 -0400
On 20/06/2020 03.47, Eli Zaretskii wrote:
>> From: Juri Linkov <juri <at> linkov.net>
>> Cc: cpitclaudel <at> gmail.com,  41200 <at> debbugs.gnu.org
>> Date: Mon, 08 Jun 2020 03:21:58 +0300
>>
>>> Could you guys please finalize these issues?  I'd like to install
>>> these changes on master, for which I'd need a patch that covers both
>>> the changes in the face storage and the fix for the tab-line face.
>>>
>>> Actually, the problem with the tab-line face will probably need to be
>>> fixed on emacs-27.
>>
>> I never used the second argument MEMBERS of 'defgroup', but it's exactly
>> what is needed.  Now the problem with the tab-line face is fixed on emacs-27
>> in commit 6eb18a950d.
> 
> Thanks.
> 
> Clément, would you like to rebase your patch on the current master and
> resubmit?  I think we are ready for installing it.

Yes, sorry for the delay.  I will try to do this today.  Thanks for your patience.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Sat, 04 Jul 2020 07:59:02 GMT) Full text and rfc822 format available.

Message #130 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Cc: 41200 <at> debbugs.gnu.org, juri <at> linkov.net
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Sat, 04 Jul 2020 10:58:15 +0300
> Cc: 41200 <at> debbugs.gnu.org
> From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
> Date: Sat, 20 Jun 2020 12:55:18 -0400
> 
> > Clément, would you like to rebase your patch on the current master and
> > resubmit?  I think we are ready for installing it.
> 
> Yes, sorry for the delay.  I will try to do this today.  Thanks for your patience.

Ping!




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Sun, 13 Sep 2020 03:31:02 GMT) Full text and rfc822 format available.

Message #133 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Benson Chu <bensonchu457 <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 41200 <at> debbugs.gnu.org
Subject: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Sat, 12 Sep 2020 21:53:22 -0500
Hey all,

I've been using this patch for 3 months now, and it makes my Emacs much
snappier! However, every time I want to update master, I have to rebase
this patch up. Is there anything preventing this changeset from landing
on master?

Is there anything I can do to help?

Also, I think there's a bug in the latest patch on line 1308 of
elisp-mode.el. The arguments for the call to remhash are reversed.

Thanks!
Benson

Eli Zaretskii <eliz <at> gnu.org> writes:

>> Cc: 41200 <at> debbugs.gnu.org
>> From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
>> Date: Sat, 20 Jun 2020 12:55:18 -0400
>> 
>> > Clément, would you like to rebase your patch on the current master and
>> > resubmit?  I think we are ready for installing it.
>> 
>> Yes, sorry for the delay.  I will try to do this today.  Thanks for your patience.
>
> Ping!




Added tag(s) patch. Request was from Lars Ingebrigtsen <larsi <at> gnus.org> to control <at> debbugs.gnu.org. (Sun, 13 Sep 2020 13:29:01 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Tue, 06 Apr 2021 10:25:02 GMT) Full text and rfc822 format available.

Message #138 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Jashank Jeremy <jashank <at> rulingia.com.au>
To: Emacs bug41200 <41200 <at> debbugs.gnu.org>
Cc: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Tue, 06 Apr 2021 16:35:28 +1000
[Message part 1 (text/plain, inline)]
Hello,

I have updated this patch to make it compile and behave on Emacs master
at 1d93540371aadec8f877bd781267d38d411c40a0 (current a few hours ago).
The updated patch is attached.

I queried Clément, who has ok'd my shepherding this patch along.

CPU profile data I've gathered suggests this change has almost entirely
stamped out the face-related hot-spots I'd seen previously.  Hooray!

Cheers,
    ~jashank

-- 
Jashank Jeremy
WWW	jashankj.space
pgp	FE4D6AA8 3736591C FAD30D97 DCE96CF5 8D931E04

[0001-Store-frame-faces-in-hash-tables-instead-of-alists-V9.patch (text/x-patch, attachment)]
[Message part 3 (application/pgp-signature, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Tue, 06 Apr 2021 12:31:02 GMT) Full text and rfc822 format available.

Message #141 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Jashank Jeremy <jashank <at> rulingia.com.au>
Cc: 41200 <at> debbugs.gnu.org, cpitclaudel <at> gmail.com
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Tue, 06 Apr 2021 15:30:17 +0300
> Date: Tue, 06 Apr 2021 16:35:28 +1000
> From: Jashank Jeremy <jashank <at> rulingia.com.au>
> Cc: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
> 
> I have updated this patch to make it compile and behave on Emacs master
> at 1d93540371aadec8f877bd781267d38d411c40a0 (current a few hours ago).
> The updated patch is attached.
> 
> I queried Clément, who has ok'd my shepherding this patch along.
> 
> CPU profile data I've gathered suggests this change has almost entirely
> stamped out the face-related hot-spots I'd seen previously.  Hooray!

Yeah, it's a pity Clément dropped the ball on this one.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Tue, 06 Apr 2021 15:08:02 GMT) Full text and rfc822 format available.

Message #144 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>, Jashank Jeremy <jashank <at> rulingia.com.au>
Cc: 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Tue, 6 Apr 2021 11:07:00 -0400
On 4/6/21 8:30 AM, Eli Zaretskii wrote:
>> Date: Tue, 06 Apr 2021 16:35:28 +1000
>> From: Jashank Jeremy <jashank <at> rulingia.com.au>
>> Cc: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
>>
>> I have updated this patch to make it compile and behave on Emacs master
>> at 1d93540371aadec8f877bd781267d38d411c40a0 (current a few hours ago).
>> The updated patch is attached.
>>
>> I queried Clément, who has ok'd my shepherding this patch along.
>>
>> CPU profile data I've gathered suggests this change has almost entirely
>> stamped out the face-related hot-spots I'd seen previously.  Hooray!
> 
> Yeah, it's a pity Clément dropped the ball on this one.

Sorry Eli, life got in the way.  I'm glad that Jashank is taking care of it :)




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Tue, 06 Apr 2021 15:51:02 GMT) Full text and rfc822 format available.

Message #147 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Cc: jashank <at> rulingia.com.au, 41200 <at> debbugs.gnu.org
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Tue, 06 Apr 2021 18:50:35 +0300
> Cc: 41200 <at> debbugs.gnu.org
> From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
> Date: Tue, 6 Apr 2021 11:07:00 -0400
> 
> Sorry Eli, life got in the way.  I'm glad that Jashank is taking care of it :)

No need to apologize, we all have that problem sometimes.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Fri, 23 Apr 2021 03:57:01 GMT) Full text and rfc822 format available.

Message #150 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Jashank Jeremy <jashank <at> rulingia.com.au>
Cc: Emacs bug41200 <41200 <at> debbugs.gnu.org>,
 Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Thu, 22 Apr 2021 23:56:20 -0400
> I have updated this patch to make it compile and behave on Emacs master
> at 1d93540371aadec8f877bd781267d38d411c40a0 (current a few hours ago).
> The updated patch is attached.

I just tried it on Emacs's `master` but for me it results in

    src/emacs -Q

opening up with most faces that don't use colors: the *scratch* buffer's
comments are displayed in black+bold+italic, the mode-line has
a black background.  A call of the form `(error "foo")` has foo display
in black+italic and the `error symbol is displayed in reverse video
(black background).

OTOH, the `M-x` that is displayed when I hit `M-x` seems to have the
usual blueish color.


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Wed, 12 May 2021 20:31:02 GMT) Full text and rfc822 format available.

Message #153 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Jashank Jeremy <jashank <at> rulingia.com.au>,
 Emacs bug41200 <41200 <at> debbugs.gnu.org>,
 Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Wed, 12 May 2021 22:29:47 +0200
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

> I just tried it on Emacs's `master` but for me it results in
>
>     src/emacs -Q
>
> opening up with most faces that don't use colors: the *scratch* buffer's
> comments are displayed in black+bold+italic, the mode-line has
> a black background.  A call of the form `(error "foo")` has foo display
> in black+italic and the `error symbol is displayed in reverse video
> (black background).

I tried the patch, too, and I'm seeing the same -- most faces are
different than they used to be, which is surely not what's supposed to
happen.

Jashank, have to continued working on this patch?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




Added tag(s) moreinfo. Request was from Lars Ingebrigtsen <larsi <at> gnus.org> to control <at> debbugs.gnu.org. (Wed, 12 May 2021 20:31:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Thu, 13 May 2021 06:53:01 GMT) Full text and rfc822 format available.

Message #158 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Jashank Jeremy <jashank <at> rulingia.com.au>
To: Lars Ingebrigtsen <larsi <at> gnus.org>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Emacs bug41200 <41200 <at> debbugs.gnu.org>,
 Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Thu, 13 May 2021 15:56:25 +1200
[Message part 1 (text/plain, inline)]
At 2021-04-22 23:56:20 -0400, Stefan Monnier wrote:
> [...] most faces that don't use colors: the *scratch* buffer's
> comments are displayed in black+bold+italic, the mode-line has a black
> background.  A call of the form `(error "foo")` has foo display in
> black+italic and the `error symbol is displayed in reverse video
> (black background).

At 2021-05-12 22:29:47 +0200, Lars Ingebrigtsen wrote:
> I tried the patch, too, and I'm seeing the same -- most faces are
> different than they used to be, which is surely not what's supposed to
> happen.

But another experiment you could try: create a new frame.  And another.

OK, I'll spoil the surprise --- this misbehaviour occurs *only* on the
initial frame.  I don't precisely know _why_ that happens, but I do know
how it broke: I tried (and thought I had succeeded) fixing a bug that
occurred only when reverse video was enabled, which would stop creation
of new frames entirely.

> Jashank, have to continued working on this patch?

Yes --- I have a patched patch which fixes that behaviour.

The 10th revision of that patch is attached: I have been running it for
a few weeks atop 7c901d90e620b4d3651b86c13faf1e81eeb3db10 (master at the
time), so I can tell you it also works with native-compile.

I have rebased onto ec574a72f7198d9793b466f33382fff397ac4ce1 (master as
of now) and will test that.

Cheers,
    ~jashank

[0001-Store-frame-faces-in-hash-tables-instead-of-alists-V10.patch (text/x-patch, attachment)]
[Message part 3 (application/pgp-signature, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Thu, 13 May 2021 09:16:01 GMT) Full text and rfc822 format available.

Message #161 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Jashank Jeremy <jashank <at> rulingia.com.au>
Cc: Emacs bug41200 <41200 <at> debbugs.gnu.org>,
 Clément Pit-Claudel <cpitclaudel <at> gmail.com>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Thu, 13 May 2021 11:15:29 +0200
Jashank Jeremy <jashank <at> rulingia.com.au> writes:

> The 10th revision of that patch is attached: I have been running it for
> a few weeks atop 7c901d90e620b4d3651b86c13faf1e81eeb3db10 (master at the
> time), so I can tell you it also works with native-compile.

I can confirm that this version fixes the face problems observed with
the previous version.

I don't see your copyright assignment papers on file -- is that in the
pipeline, or have you yet to start the assignment process?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Thu, 13 May 2021 23:28:02 GMT) Full text and rfc822 format available.

Message #164 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Jashank Jeremy <jashank <at> rulingia.com.au>
To: Lars Ingebrigtsen <larsi <at> gnus.org>
Cc: Emacs bug41200 <41200 <at> debbugs.gnu.org>,
 Clément Pit-Claudel <cpitclaudel <at> gmail.com>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Fri, 14 May 2021 11:26:55 +1200
[Message part 1 (text/plain, inline)]
At 2021-05-13 11:15:29 +0200, Lars Ingebrigtsen wrote:
> Jashank Jeremy <jashank <at> rulingia.com.au> writes:
>> The 10th revision of that patch is attached: I have been running it for
>> a few weeks atop 7c901d90e620b4d3651b86c13faf1e81eeb3db10 (master at the
>> time), so I can tell you it also works with native-compile.
>
> I can confirm that this version fixes the face problems observed with
> the previous version.

Excellent, thanks.

> I don't see your copyright assignment papers on file -- is that in the
> pipeline, or have you yet to start the assignment process?

Started ... but presently stalled due to the employer pipeline hazard.

    ~jashank
[Message part 2 (application/pgp-signature, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Sat, 12 Jun 2021 12:16:02 GMT) Full text and rfc822 format available.

Message #167 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Jashank Jeremy <jashank <at> rulingia.com.au>
Cc: Emacs bug41200 <41200 <at> debbugs.gnu.org>,
 Clément Pit-Claudel <cpitclaudel <at> gmail.com>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Sat, 12 Jun 2021 14:15:45 +0200
Jashank Jeremy <jashank <at> rulingia.com.au> writes:

>> I don't see your copyright assignment papers on file -- is that in the
>> pipeline, or have you yet to start the assignment process?
>
> Started ... but presently stalled due to the employer pipeline hazard.

This was a month ago -- has there been any further progress here?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Sun, 13 Jun 2021 03:20:02 GMT) Full text and rfc822 format available.

Message #170 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Richard Stallman <rms <at> gnu.org>
To: Lars Ingebrigtsen <larsi <at> gnus.org>
Cc: jashank <at> rulingia.com.au, 41200 <at> debbugs.gnu.org, cpitclaudel <at> gmail.com,
 monnier <at> iro.umontreal.ca
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Sat, 12 Jun 2021 23:19:26 -0400
[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > >> I don't see your copyright assignment papers on file -- is that in the
  > >> pipeline, or have you yet to start the assignment process?
  > >
  > > Started ... but presently stalled due to the employer pipeline hazard.

  > This was a month ago -- has there been any further progress here?

Talking with people at the employer, and with the FSF staff, and
encouraging them to talk with each other, could enable them to unblock
it.  Some companies' lawyers look at the issue in a very narrow way,
and the FSF staff could help them see a solution.

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)






Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Tue, 06 Jul 2021 12:43:02 GMT) Full text and rfc822 format available.

Message #173 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Aaron Jensen <aaronjensen <at> gmail.com>
To: Lars Ingebrigtsen <larsi <at> gnus.org>
Cc: jashank <at> rulingia.com.au, 41200 <at> debbugs.gnu.org, cpitclaudel <at> gmail.com,
 monnier <at> iro.umontreal.ca
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Tue, 06 Jul 2021 05:41:56 -0700
Lars Ingebrigtsen <larsi <at> gnus.org> writes:

> Jashank Jeremy <jashank <at> rulingia.com.au> writes:
>
>>> I don't see your copyright assignment papers on file -- is that in the
>>> pipeline, or have you yet to start the assignment process?
>>
>> Started ... but presently stalled due to the employer pipeline hazard.
>
>This was a month ago -- has there been any further progress here?

Is there any chance that Clément could pick this up from his original
patch and avoid waiting for copyright assignment of the
corrected/up-to-date patch? I'd do it mysel if I were more familiar with
the code, but I'm not.

Aaron




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Wed, 21 Jul 2021 14:03:01 GMT) Full text and rfc822 format available.

Message #176 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Jashank Jeremy <jashank <at> rulingia.com.au>
Cc: Emacs bug41200 <41200 <at> debbugs.gnu.org>,
 Clément Pit-Claudel <cpitclaudel <at> gmail.com>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Wed, 21 Jul 2021 16:02:12 +0200
Jashank Jeremy <jashank <at> rulingia.com.au> writes:

> Yes --- I have a patched patch which fixes that behaviour.
>
> The 10th revision of that patch is attached: I have been running it for
> a few weeks atop 7c901d90e620b4d3651b86c13faf1e81eeb3db10 (master at the
> time), so I can tell you it also works with native-compile.
>
> I have rebased onto ec574a72f7198d9793b466f33382fff397ac4ce1 (master as
> of now) and will test that.

I see that the copyright assignment paperwork was finished a couple of
weeks ago, so I've now re-tested your patch, and I can't see any
glitches, so I've pushed it to Emacs 28.

Thanks!

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




bug marked as fixed in version 28.1, send any further explanations to 41200 <at> debbugs.gnu.org and Clément Pit-Claudel <cpitclaudel <at> gmail.com> Request was from Lars Ingebrigtsen <larsi <at> gnus.org> to control <at> debbugs.gnu.org. (Wed, 21 Jul 2021 14:03:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Wed, 21 Jul 2021 14:29:01 GMT) Full text and rfc822 format available.

Message #181 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Lars Ingebrigtsen <larsi <at> gnus.org>
Cc: Jashank Jeremy <jashank <at> rulingia.com.au>,
 Emacs bug41200 <41200 <at> debbugs.gnu.org>,
 Clément Pit-Claudel <cpitclaudel <at> gmail.com>
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow
 as more faces are defined
Date: Wed, 21 Jul 2021 10:28:45 -0400
Lars Ingebrigtsen [2021-07-21 16:02:12] wrote:
> I see that the copyright assignment paperwork was finished a couple of
> weeks ago, so I've now re-tested your patch, and I can't see any
> glitches, so I've pushed it to Emacs 28.

Yay!


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#41200; Package emacs. (Wed, 21 Jul 2021 14:34:01 GMT) Full text and rfc822 format available.

Message #184 received at 41200 <at> debbugs.gnu.org (full text, mbox):

From: Clément Pit-Claudel <cpitclaudel <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>,
 Lars Ingebrigtsen <larsi <at> gnus.org>
Cc: Jashank Jeremy <jashank <at> rulingia.com.au>,
 Emacs bug41200 <41200 <at> debbugs.gnu.org>
Subject: Re: bug#41200: Displaying a tooltip with x-show-tip gets very slow as
 more faces are defined
Date: Wed, 21 Jul 2021 10:32:52 -0400
On 7/21/21 10:28 AM, Stefan Monnier wrote:
> Lars Ingebrigtsen [2021-07-21 16:02:12] wrote:
>> I see that the copyright assignment paperwork was finished a couple of
>> weeks ago, so I've now re-tested your patch, and I can't see any
>> glitches, so I've pushed it to Emacs 28.

Thanks everyone!

Now to figure why tooltips are blinking so much lately ^^ (it's from before this patch)




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Thu, 19 Aug 2021 11:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 2 years and 245 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.