* bug#71454: 30.0.50; Performance issues with font selection
@ 2024-06-09 18:56 Kai Ma
2024-06-09 22:10 ` Jeremy Bryant via Bug reports for GNU Emacs, the Swiss army knife of text editors
` (2 more replies)
0 siblings, 3 replies; 26+ messages in thread
From: Kai Ma @ 2024-06-09 18:56 UTC (permalink / raw)
To: 71454
Recently, I have the need of editing files with extraordinary ranges of
Unicode code points, and the performance problem with font selection
becomes too obvious to ignore.
I have currently (length (font-family-list)) = 582 font families
installed. And whenever I input some ununsual characters, Emacs will
freeze for seconds until I am able to do anything else. Worse, the
freeze delay for each character will add up. And whenver the face
changes (including hl-line-mode), or I switched to another buffer for
some time, there will be a delay again.
I'm pretty sure this is due to font selection, because Emacs won't
freeze if I configure manually the fallback fonts for each 'exotic'
script I encounter.
For testing, there are some such characters in my file:
〡〢〣〤〥〦〨〩〸〹〺
[ū, ú, ű, ǔ, ù, ȕ, û, ŭ, ȗ, ü, ǖ, ǘ, ǚ, ǜ, ů, ũ, ᵤ, ᵘ, ʉ, ᶶ, ủ, ų, ṷ, ụ,
ṳ, ṵ, ư, ʊ, ᶷ, ᵿ, ᶙ, ṻ, ṹ, ứ, ừ, ữ, ử, ự, ꭒ, ꭟ, ꝸ, ꭎ, ꭏ, ᴝ, ᵙ, ᴞ]
[ü, ǖ, ǘ, ǚ, ǜ, ṽ, ᵛ, ᵥ, ṿ, ꝟ, ʋ, ᶹ, ᶌ, ⱴ, ⱱ, ỽ, ʌ, ᶺ]
[Ü, Ǖ, Ǘ, Ǚ, Ǜ, Ṽ, ᴠ, ⱽ, Ṿ, Ꝟ, Ʋ, Ỽ, Ʌ ]
[ ₀, ₁, ₂, ₃, ₄, ₅, ₆, ₇, ₈, ₉, ₊, ₋, ₌, ₍, ₎, ‸, ᴀ, ₐ, ᴁ, ʙ, ᴃ, ᵦ, ᴄ, ᴐ, ᴒ, ᴅ, ᴆ, ᴇ, ₑ, ₔ, ᵩ, ɢ, ʛ, ᴦ, ᵧ, ʜ, ₕ, ɪ, ᵻ, ᵢ, ᴊ, ⱼ, ᴋ, ₖ, ʟ, ₗ, ᴌ, ᴧ, ᴍ, ₘ, ꟺ, ɴ, ᴎ, ₙ, ᴏ, ₒ, ɶ, ʘ, ᴓ, ᴑ, ᴘ, ₚ, ᴨ, ᴪ, ʀ, ᵣ, ᴙ, ʁ, ᴚ, ᵨ, ₛ, ᴛ, ₜ, ᴜ, ᵤ, ᵾ, ᴠ, ᵥ, ᴡ, ₓ, ᵪ, ʏ, ᴢ, ᴣ ]
[ 五, 伍, ₅, ⁵, Ⅴ, ⅴ, ⑤, ➄, ❺, ➎, ⓹, ⑸, ⒌, 5, ㊄, ㈤, 㐅, 㠪, 𠄡 ]
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-09 18:56 bug#71454: 30.0.50; Performance issues with font selection Kai Ma
@ 2024-06-09 22:10 ` Jeremy Bryant via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-09 22:17 ` Kai Ma
2024-06-10 11:58 ` Eli Zaretskii
[not found] ` <22612F93-FC37-48E8-8137-E9FF6F5B3A0D@gmail.com>
2 siblings, 1 reply; 26+ messages in thread
From: Jeremy Bryant via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-09 22:10 UTC (permalink / raw)
To: Kai Ma; +Cc: 71454
Kai Ma <justksqsf@gmail.com> writes:
> Recently, I have the need of editing files with extraordinary ranges of
> Unicode code points, and the performance problem with font selection
> becomes too obvious to ignore.
>
> I have currently (length (font-family-list)) = 582 font families
> installed. And whenever I input some ununsual characters, Emacs will
> freeze for seconds until I am able to do anything else. Worse, the
> freeze delay for each character will add up. And whenver the face
> changes (including hl-line-mode), or I switched to another buffer for
> some time, there will be a delay again.
>
> I'm pretty sure this is due to font selection, because Emacs won't
> freeze if I configure manually the fallback fonts for each 'exotic'
> script I encounter.
>
> For testing, there are some such characters in my file:
>
> 〡〢〣〤〥〦〨〩〸〹〺
>
> [ū, ú, ű, ǔ, ù, ȕ, û, ŭ, ȗ, ü, ǖ, ǘ, ǚ, ǜ, ů, ũ, ᵤ, ᵘ, ʉ, ᶶ, ủ, ų, ṷ, ụ,
> ṳ, ṵ, ư, ʊ, ᶷ, ᵿ, ᶙ, ṻ, ṹ, ứ, ừ, ữ, ử, ự, ꭒ, ꭟ, ꝸ, ꭎ, ꭏ, ᴝ, ᵙ, ᴞ]
>
> [ü, ǖ, ǘ, ǚ, ǜ, ṽ, ᵛ, ᵥ, ṿ, ꝟ, ʋ, ᶹ, ᶌ, ⱴ, ⱱ, ỽ, ʌ, ᶺ]
>
> [Ü, Ǖ, Ǘ, Ǚ, Ǜ, Ṽ, ᴠ, ⱽ, Ṿ, Ꝟ, Ʋ, Ỽ, Ʌ ]
>
> [ ₀, ₁, ₂, ₃, ₄, ₅, ₆, ₇, ₈, ₉, ₊, ₋, ₌, ₍, ₎, ‸, ᴀ, ₐ, ᴁ, ʙ, ᴃ, ᵦ, ᴄ, ᴐ, ᴒ, ᴅ, ᴆ, ᴇ, ₑ, ₔ, ᵩ, ɢ, ʛ, ᴦ, ᵧ, ʜ, ₕ, ɪ, ᵻ, ᵢ, ᴊ, ⱼ, ᴋ, ₖ, ʟ, ₗ, ᴌ, ᴧ, ᴍ, ₘ, ꟺ, ɴ, ᴎ, ₙ, ᴏ, ₒ, ɶ, ʘ, ᴓ, ᴑ, ᴘ, ₚ, ᴨ, ᴪ, ʀ, ᵣ, ᴙ, ʁ, ᴚ, ᵨ, ₛ, ᴛ, ₜ, ᴜ, ᵤ, ᵾ, ᴠ, ᵥ, ᴡ, ₓ, ᵪ, ʏ, ᴢ, ᴣ ]
>
> [ 五, 伍, ₅, ⁵, Ⅴ, ⅴ, ⑤, ➄, ❺, ➎, ⓹, ⑸, ⒌, 5, ㊄, ㈤, 㐅, 㠪, 𠄡 ]
Would you be able to provide a self-contained series of steps starting
from emacs -Q?
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-09 22:10 ` Jeremy Bryant via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-09 22:17 ` Kai Ma
2024-06-09 22:34 ` Jeremy Bryant via Bug reports for GNU Emacs, the Swiss army knife of text editors
` (2 more replies)
0 siblings, 3 replies; 26+ messages in thread
From: Kai Ma @ 2024-06-09 22:17 UTC (permalink / raw)
To: Jeremy Bryant; +Cc: 71454
> On Jun 10, 2024, at 00:10, Jeremy Bryant <jb@jeremybryant.net> wrote:
>
> Would you be able to provide a self-contained series of steps starting
> from emacs -Q?
On my machine it is extremely easy to reproduce by simply:
1. emacs -Q
2. Switch to *scratch*
3. Copy the provided text into *scratch*
4. Emacs will freeze for 17 seconds or so, and it cannot be interrupted by C-g
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-09 22:17 ` Kai Ma
@ 2024-06-09 22:34 ` Jeremy Bryant via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-10 2:14 ` Kai Ma
2024-06-09 23:10 ` Jim Porter
2024-06-10 11:55 ` Eli Zaretskii
2 siblings, 1 reply; 26+ messages in thread
From: Jeremy Bryant via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-09 22:34 UTC (permalink / raw)
To: Kai Ma; +Cc: 71454
Kai Ma <justksqsf@gmail.com> writes:
>> On Jun 10, 2024, at 00:10, Jeremy Bryant <jb@jeremybryant.net> wrote:
>>
>> Would you be able to provide a self-contained series of steps starting
>> from emacs -Q?
>
> On my machine it is extremely easy to reproduce by simply:
>
> 1. emacs -Q
> 2. Switch to *scratch*
> 3. Copy the provided text into *scratch*
> 4. Emacs will freeze for 17 seconds or so, and it cannot be interrupted by C-g
I am unable to reproduce this bug.
Please could you specify exactly which version of Emacs you are using?
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-09 22:34 ` Jeremy Bryant via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-10 2:14 ` Kai Ma
2024-06-10 12:04 ` Eli Zaretskii
0 siblings, 1 reply; 26+ messages in thread
From: Kai Ma @ 2024-06-10 2:14 UTC (permalink / raw)
To: Jeremy Bryant; +Cc: 71454
> On Jun 10, 2024, at 00:34, Jeremy Bryant <jb@jeremybryant.net> wrote:
>
> Kai Ma <justksqsf@gmail.com> writes:
>
>>> On Jun 10, 2024, at 00:10, Jeremy Bryant <jb@jeremybryant.net> wrote:
>>>
>>> Would you be able to provide a self-contained series of steps starting
>>> from emacs -Q?
>>
>> On my machine it is extremely easy to reproduce by simply:
>>
>> 1. emacs -Q
>> 2. Switch to *scratch*
>> 3. Copy the provided text into *scratch*
>> 4. Emacs will freeze for 17 seconds or so, and it cannot be interrupted by C-g
>
> I am unable to reproduce this bug.
>
> Please could you specify exactly which version of Emacs you are using?
I’m using Emacs master branch (commit 7f8ded2a85d) on macOS.
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-10 2:14 ` Kai Ma
@ 2024-06-10 12:04 ` Eli Zaretskii
0 siblings, 0 replies; 26+ messages in thread
From: Eli Zaretskii @ 2024-06-10 12:04 UTC (permalink / raw)
To: Kai Ma; +Cc: jb, 71454
> Cc: 71454@debbugs.gnu.org
> From: Kai Ma <justksqsf@gmail.com>
> Date: Mon, 10 Jun 2024 04:14:40 +0200
>
>
>
> > On Jun 10, 2024, at 00:34, Jeremy Bryant <jb@jeremybryant.net> wrote:
> >
> > Kai Ma <justksqsf@gmail.com> writes:
> >
> >>> On Jun 10, 2024, at 00:10, Jeremy Bryant <jb@jeremybryant.net> wrote:
> >>>
> >>> Would you be able to provide a self-contained series of steps starting
> >>> from emacs -Q?
> >>
> >> On my machine it is extremely easy to reproduce by simply:
> >>
> >> 1. emacs -Q
> >> 2. Switch to *scratch*
> >> 3. Copy the provided text into *scratch*
> >> 4. Emacs will freeze for 17 seconds or so, and it cannot be interrupted by C-g
> >
> > I am unable to reproduce this bug.
> >
> > Please could you specify exactly which version of Emacs you are using?
>
> I’m using Emacs master branch (commit 7f8ded2a85d) on macOS.
Maybe this is specific to the macOS font back-end, which AFAIU is a
special one used only on macOS.
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-09 22:17 ` Kai Ma
2024-06-09 22:34 ` Jeremy Bryant via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-09 23:10 ` Jim Porter
2024-06-10 2:18 ` Kai Ma
2024-06-10 11:55 ` Eli Zaretskii
2 siblings, 1 reply; 26+ messages in thread
From: Jim Porter @ 2024-06-09 23:10 UTC (permalink / raw)
To: Kai Ma, Jeremy Bryant; +Cc: 71454
On 6/9/2024 3:17 PM, Kai Ma wrote:
>
>> On Jun 10, 2024, at 00:10, Jeremy Bryant <jb@jeremybryant.net> wrote:
>>
>> Would you be able to provide a self-contained series of steps starting
>> from emacs -Q?
>
> On my machine it is extremely easy to reproduce by simply:
>
> 1. emacs -Q
> 2. Switch to *scratch*
> 3. Copy the provided text into *scratch*
> 4. Emacs will freeze for 17 seconds or so, and it cannot be interrupted by C-g
Is this on MS-Windows, by chance? Using a different set of steps, I can
reproduce this issue on MS-Windows (Emacs 29.3), but not on GNU/Linux.
Here's what I did:
emacs -Q
C-h v comint-password-prompt-regexp RET
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-09 23:10 ` Jim Porter
@ 2024-06-10 2:18 ` Kai Ma
2024-06-10 11:53 ` Eli Zaretskii
0 siblings, 1 reply; 26+ messages in thread
From: Kai Ma @ 2024-06-10 2:18 UTC (permalink / raw)
To: Jim Porter; +Cc: Jeremy Bryant, 71454
> On Jun 10, 2024, at 01:10, Jim Porter <jporterbugs@gmail.com> wrote:
>
> On 6/9/2024 3:17 PM, Kai Ma wrote:
>>> On Jun 10, 2024, at 00:10, Jeremy Bryant <jb@jeremybryant.net> wrote:
>>>
>>> Would you be able to provide a self-contained series of steps starting
>>> from emacs -Q?
>> On my machine it is extremely easy to reproduce by simply:
>> 1. emacs -Q
>> 2. Switch to *scratch*
>> 3. Copy the provided text into *scratch*
>> 4. Emacs will freeze for 17 seconds or so, and it cannot be interrupted by C-g
>
> Is this on MS-Windows, by chance? Using a different set of steps, I can reproduce this issue on MS-Windows (Emacs 29.3), but not on GNU/Linux. Here's what I did:
>
> emacs -Q
> C-h v comint-password-prompt-regexp RET
I’m using macOS. I apologize for not adding this info to my original report.
And yes, I can also reproduce the issue with C-h v comint-password-prompt-regexp RET
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-10 2:18 ` Kai Ma
@ 2024-06-10 11:53 ` Eli Zaretskii
2024-06-10 16:31 ` Jim Porter
0 siblings, 1 reply; 26+ messages in thread
From: Eli Zaretskii @ 2024-06-10 11:53 UTC (permalink / raw)
To: Kai Ma; +Cc: jporterbugs, jb, 71454
severity 71454 wishlist
thanks
> Cc: Jeremy Bryant <jb@jeremybryant.net>, 71454@debbugs.gnu.org
> From: Kai Ma <justksqsf@gmail.com>
> Date: Mon, 10 Jun 2024 04:18:08 +0200
>
> > On Jun 10, 2024, at 01:10, Jim Porter <jporterbugs@gmail.com> wrote:
> >
> > On 6/9/2024 3:17 PM, Kai Ma wrote:
> >>> On Jun 10, 2024, at 00:10, Jeremy Bryant <jb@jeremybryant.net> wrote:
> >>>
> >>> Would you be able to provide a self-contained series of steps starting
> >>> from emacs -Q?
> >> On my machine it is extremely easy to reproduce by simply:
> >> 1. emacs -Q
> >> 2. Switch to *scratch*
> >> 3. Copy the provided text into *scratch*
> >> 4. Emacs will freeze for 17 seconds or so, and it cannot be interrupted by C-g
> >
> > Is this on MS-Windows, by chance? Using a different set of steps, I can reproduce this issue on MS-Windows (Emacs 29.3), but not on GNU/Linux. Here's what I did:
> >
> > emacs -Q
> > C-h v comint-password-prompt-regexp RET
>
>
> I’m using macOS. I apologize for not adding this info to my original report.
>
> And yes, I can also reproduce the issue with C-h v comint-password-prompt-regexp RET
AFAICT, the problematic part of comint-password-prompt-regexp is this:
गुप्तशब्द\\|शब्दकूट\\|গুপ্তশব্দ\\|পাসওয়ার্ড\\|ਪਾਸਵਰਡ\\|પાસવર્ડ\\|ପ୍ରବେଶ ସଙ୍କେତ\\|கடவுச்சொல்\\|సంకేతపదము\\|ಗುಪ್ತಪದ\\|അടയാളവാക്ക്\\|රහස්පදය
This has nothing to do with the number of fonts installed on the
system, nor with how Emacs searches for fonts, nor even with the fonts
themselves. On my system, all of the characters above are displayed
using the same single font. And yet, even if I insert just a single
character of those, which causes Emacs to find and load that font,
pasting the rest of the string takes several seconds in an unoptimized
build (I expect it to take about 2 sec or less in an optimized build).
Note that if you then paste the same string over and over again, the
display is instantaneous.
My crystal ball says that the expensive part here is character
composition. The above characters belong to scripts that require
extensive composition rules, take a look at indian.el and its complex
regexps. Displaying those characters requires the display code to
examine all those regexps, to find the largest composable sequence,
then generate the compositions by calling into Lisp, which then calls
back into C where we call HarfBuzz to produce the font glyphs for the
compositions. This is expensive, and so Emacs caches each composition
for further use, which explains why subsequent pastes are much faster.
IOW, this is a price we pay for the fact that we make character
compositions infinitely customizable on the Lisp level.
So far, I see no bug here. Of course, if someone wants to work on
redesign of how Emacs handles character composition, and as part of
such a redesign will make the process much faster, that would be very
welcome.
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-10 11:53 ` Eli Zaretskii
@ 2024-06-10 16:31 ` Jim Porter
2024-06-10 17:35 ` Eli Zaretskii
0 siblings, 1 reply; 26+ messages in thread
From: Jim Porter @ 2024-06-10 16:31 UTC (permalink / raw)
To: Eli Zaretskii, Kai Ma; +Cc: jb, 71454
On 6/10/2024 4:53 AM, Eli Zaretskii wrote:
> My crystal ball says that the expensive part here is character
> composition. The above characters belong to scripts that require
> extensive composition rules, take a look at indian.el and its complex
> regexps.
That would show up in a profile, right? Here's what I get when I start
"emacs -Q", start profiling, and then call "C-h v
comint-password-prompt-regexp RET". It's not the most interesting
profile since most of it is probably in C code. I do see
'auto-compose-chars' in there, however it's got ~0% of the samples from
the profiler.
I haven't had time to dig into this in any great depth, so this profile
may of course turn out to be entirely useless...
910 98% - command-execute
907 98% - funcall-interactively
907 98% - describe-variable
907 98% - help--window-setup
905 98% - help-window-setup
2 0% - help-window-display-message
2 0% auto-compose-chars
1 0% - #<compiled 0x14e8696a6b1e2e3f>
1 0% - cl-prin1-to-string
1 0% - byte-code
1 0% - cl-generic-define-method
1 0% - cl--generic-make-function
1 0% - cl--generic-make-next-function
1 0% - cl--generic-get-dispatcher
1 0% - byte-compile
1 0% - #<subr
F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_50>
1 0% byte-compile-top-level
1 0% help-make-xrefs
3 0% - byte-code
2 0% - read-extended-command
2 0% - read-extended-command-1
2 0% completing-read-default
1 0% - variable-at-point
1 0% - find-tag-default
1 0% find-tag-default-bounds
10 1% - ...
9 0% Automatic GC
1 0% - completion--in-region
1 0% - #<compiled -0x68df6976d72fd66>
1 0% - apply
1 0% - #<compiled -0x1e70b1692b6b395e>
1 0% - completion--in-region-1
1 0% - completion--do-completion
1 0% - completion-try-completion
1 0% - completion--nth-completion
1 0% - completion--some
1 0% - #<compiled 0x3d94d2d3a4c0012>
1 0% - completion-basic-try-completion
1 0% - completion-boundaries
1 0% - help--symbol-completion-table
1 0% - help--load-prefixes
1 0% - load
1 0% byte-code
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-10 16:31 ` Jim Porter
@ 2024-06-10 17:35 ` Eli Zaretskii
0 siblings, 0 replies; 26+ messages in thread
From: Eli Zaretskii @ 2024-06-10 17:35 UTC (permalink / raw)
To: Jim Porter; +Cc: justksqsf, 71454, jb
> Date: Mon, 10 Jun 2024 09:31:53 -0700
> Cc: jb@jeremybryant.net, 71454@debbugs.gnu.org
> From: Jim Porter <jporterbugs@gmail.com>
>
> On 6/10/2024 4:53 AM, Eli Zaretskii wrote:
> > My crystal ball says that the expensive part here is character
> > composition. The above characters belong to scripts that require
> > extensive composition rules, take a look at indian.el and its complex
> > regexps.
>
> That would show up in a profile, right?
No, because Lisp functions called from C don't show in the profile.
> Here's what I get when I start "emacs -Q", start profiling, and then
> call "C-h v comint-password-prompt-regexp RET". It's not the most
> interesting profile since most of it is probably in C code. I do see
> 'auto-compose-chars' in there, however it's got ~0% of the samples
> from the profiler.
As expected, see above.
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-09 22:17 ` Kai Ma
2024-06-09 22:34 ` Jeremy Bryant via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-09 23:10 ` Jim Porter
@ 2024-06-10 11:55 ` Eli Zaretskii
2024-06-10 12:35 ` Kai Ma
2 siblings, 1 reply; 26+ messages in thread
From: Eli Zaretskii @ 2024-06-10 11:55 UTC (permalink / raw)
To: Kai Ma; +Cc: jb, 71454
> Cc: 71454@debbugs.gnu.org
> From: Kai Ma <justksqsf@gmail.com>
> Date: Mon, 10 Jun 2024 00:17:55 +0200
>
>
> > On Jun 10, 2024, at 00:10, Jeremy Bryant <jb@jeremybryant.net> wrote:
> >
> > Would you be able to provide a self-contained series of steps starting
> > from emacs -Q?
>
> On my machine it is extremely easy to reproduce by simply:
>
> 1. emacs -Q
> 2. Switch to *scratch*
> 3. Copy the provided text into *scratch*
> 4. Emacs will freeze for 17 seconds or so, and it cannot be interrupted by C-g
I cannot reproduce this, I get an almost instantaneous redisplay with
those characters.
When your Emacs eventually displays the text, how many characters are
shown as boxes with hex code, and which ones are those?
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-10 11:55 ` Eli Zaretskii
@ 2024-06-10 12:35 ` Kai Ma
2024-06-10 12:59 ` Eli Zaretskii
0 siblings, 1 reply; 26+ messages in thread
From: Kai Ma @ 2024-06-10 12:35 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Jeremy Bryant, 71454
> On Jun 10, 2024, at 13:55, Eli Zaretskii <eliz@gnu.org> wrote:
>
>> Cc: 71454@debbugs.gnu.org
>> From: Kai Ma <justksqsf@gmail.com>
>> Date: Mon, 10 Jun 2024 00:17:55 +0200
>>
>>
>>> On Jun 10, 2024, at 00:10, Jeremy Bryant <jb@jeremybryant.net> wrote:
>>>
>>> Would you be able to provide a self-contained series of steps starting
>>> from emacs -Q?
>>
>> On my machine it is extremely easy to reproduce by simply:
>>
>> 1. emacs -Q
>> 2. Switch to *scratch*
>> 3. Copy the provided text into *scratch*
>> 4. Emacs will freeze for 17 seconds or so, and it cannot be interrupted by C-g
>
> I cannot reproduce this, I get an almost instantaneous redisplay with
> those characters.
>
> When your Emacs eventually displays the text, how many characters are
> shown as boxes with hex code, and which ones are those?
None are hex code here. They eventually get displayed, but it takes a long time.
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-10 12:35 ` Kai Ma
@ 2024-06-10 12:59 ` Eli Zaretskii
2024-06-10 16:42 ` Gerd Möllmann
0 siblings, 1 reply; 26+ messages in thread
From: Eli Zaretskii @ 2024-06-10 12:59 UTC (permalink / raw)
To: Kai Ma; +Cc: jb, 71454
> From: Kai Ma <justksqsf@gmail.com>
> Date: Mon, 10 Jun 2024 14:35:50 +0200
> Cc: Jeremy Bryant <jb@jeremybryant.net>,
> 71454@debbugs.gnu.org
>
>
>
> > On Jun 10, 2024, at 13:55, Eli Zaretskii <eliz@gnu.org> wrote:
> >
> >> Cc: 71454@debbugs.gnu.org
> >> From: Kai Ma <justksqsf@gmail.com>
> >> Date: Mon, 10 Jun 2024 00:17:55 +0200
> >>
> >>
> >>> On Jun 10, 2024, at 00:10, Jeremy Bryant <jb@jeremybryant.net> wrote:
> >>>
> >>> Would you be able to provide a self-contained series of steps starting
> >>> from emacs -Q?
> >>
> >> On my machine it is extremely easy to reproduce by simply:
> >>
> >> 1. emacs -Q
> >> 2. Switch to *scratch*
> >> 3. Copy the provided text into *scratch*
> >> 4. Emacs will freeze for 17 seconds or so, and it cannot be interrupted by C-g
> >
> > I cannot reproduce this, I get an almost instantaneous redisplay with
> > those characters.
> >
> > When your Emacs eventually displays the text, how many characters are
> > shown as boxes with hex code, and which ones are those?
>
> None are hex code here. They eventually get displayed, but it takes a long time.
Then it definitely sounds like macOS specific. Does anyone know how
Emacs on macOS searches for fonts, and whether there are any
font-caching facilities, either in Emacs or by the OS?
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-10 12:59 ` Eli Zaretskii
@ 2024-06-10 16:42 ` Gerd Möllmann
2024-06-10 17:36 ` Kai Ma
0 siblings, 1 reply; 26+ messages in thread
From: Gerd Möllmann @ 2024-06-10 16:42 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Kai Ma, 71454, jb
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Kai Ma <justksqsf@gmail.com>
>> Date: Mon, 10 Jun 2024 14:35:50 +0200
>> Cc: Jeremy Bryant <jb@jeremybryant.net>,
>> 71454@debbugs.gnu.org
>>
>>
>>
>> > On Jun 10, 2024, at 13:55, Eli Zaretskii <eliz@gnu.org> wrote:
>> >
>> >> Cc: 71454@debbugs.gnu.org
>> >> From: Kai Ma <justksqsf@gmail.com>
>> >> Date: Mon, 10 Jun 2024 00:17:55 +0200
>> >>
>> >>
>> >>> On Jun 10, 2024, at 00:10, Jeremy Bryant <jb@jeremybryant.net> wrote:
>> >>>
>> >>> Would you be able to provide a self-contained series of steps starting
>> >>> from emacs -Q?
>> >>
>> >> On my machine it is extremely easy to reproduce by simply:
>> >>
>> >> 1. emacs -Q
>> >> 2. Switch to *scratch*
>> >> 3. Copy the provided text into *scratch*
>> >> 4. Emacs will freeze for 17 seconds or so, and it cannot be interrupted by C-g
>> >
>> > I cannot reproduce this, I get an almost instantaneous redisplay with
>> > those characters.
>> >
>> > When your Emacs eventually displays the text, how many characters are
>> > shown as boxes with hex code, and which ones are those?
>>
>> None are hex code here. They eventually get displayed, but it takes a long time.
>
> Then it definitely sounds like macOS specific. Does anyone know how
> Emacs on macOS searches for fonts, and whether there are any
> font-caching facilities, either in Emacs or by the OS?
Don't know, but the display of the strings mentioned is instantaneous
here too (macOS 14.5), with (length (font-family-list)) == 281.
Maybe use the Font Book app and see if the fonts are all valid? (Start
Font Book, choose All Fonts, select them all with Command + A, then
context menu on the selectoin and choose Validate.)
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-10 16:42 ` Gerd Möllmann
@ 2024-06-10 17:36 ` Kai Ma
2024-06-10 18:05 ` Gerd Möllmann
0 siblings, 1 reply; 26+ messages in thread
From: Kai Ma @ 2024-06-10 17:36 UTC (permalink / raw)
To: Gerd Möllmann; +Cc: Eli Zaretskii, 71454, Jeremy Bryant
> On Jun 10, 2024, at 18:42, Gerd Möllmann <gerd.moellmann@gmail.com> wrote:
> […]
> Maybe use the Font Book app and see if the fonts are all valid? (Start
> Font Book, choose All Fonts, select them all with Command + A, then
> context menu on the selectoin and choose Validate.)
I do get some warnings. Font Book shows “52 minor problems were found”. Most are “Duplicate fonts”, but there are also real warnings like “name table structure”.
To clear these warnings, I moved all font files in ~/Library/Fonts elsewhere, but the problem still persists, though the delay for the testing text is much shorter (about 5s now).
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-10 17:36 ` Kai Ma
@ 2024-06-10 18:05 ` Gerd Möllmann
0 siblings, 0 replies; 26+ messages in thread
From: Gerd Möllmann @ 2024-06-10 18:05 UTC (permalink / raw)
To: Kai Ma; +Cc: Eli Zaretskii, 71454, Jeremy Bryant
Kai Ma <justksqsf@gmail.com> writes:
>> On Jun 10, 2024, at 18:42, Gerd Möllmann <gerd.moellmann@gmail.com> wrote:
>> […]
>> Maybe use the Font Book app and see if the fonts are all valid? (Start
>> Font Book, choose All Fonts, select them all with Command + A, then
>> context menu on the selectoin and choose Validate.)
>
> I do get some warnings. Font Book shows “52 minor problems were
> found”. Most are “Duplicate fonts”, but there are also real warnings
> like “name table structure”.
>
> To clear these warnings, I moved all font files in ~/Library/Fonts
> elsewhere, but the problem still persists, though the delay for the
> testing text is much shorter (about 5s now).
Progress :-).
Rumours have it that one can clear system caches (just to make sure) by
performing a safe boot (https://support.apple.com/en-gb/116946), and
then restarting normally.
And then there is the atsutil command line utitlity. Though I must say
that I never had to use that one, and so I can't say if it's
dangerous... (man atsutil).
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-09 18:56 bug#71454: 30.0.50; Performance issues with font selection Kai Ma
2024-06-09 22:10 ` Jeremy Bryant via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-10 11:58 ` Eli Zaretskii
2024-06-10 12:34 ` Kai Ma
[not found] ` <22612F93-FC37-48E8-8137-E9FF6F5B3A0D@gmail.com>
2 siblings, 1 reply; 26+ messages in thread
From: Eli Zaretskii @ 2024-06-10 11:58 UTC (permalink / raw)
To: Kai Ma; +Cc: 71454
> From: Kai Ma <justksqsf@gmail.com>
> Date: Sun, 9 Jun 2024 20:56:47 +0200
>
> I have currently (length (font-family-list)) = 582 font families
> installed. And whenever I input some ununsual characters, Emacs will
> freeze for seconds until I am able to do anything else. Worse, the
> freeze delay for each character will add up. And whenver the face
> changes (including hl-line-mode), or I switched to another buffer for
> some time, there will be a delay again.
FTR, I have 553 font families, and I see no significant delay when
pasting the characters you show.
> I'm pretty sure this is due to font selection, because Emacs won't
> freeze if I configure manually the fallback fonts for each 'exotic'
> script I encounter.
If this is the case, please tell the details: which fonts you need to
configure manually to eliminate the delay.
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-10 11:58 ` Eli Zaretskii
@ 2024-06-10 12:34 ` Kai Ma
2024-06-10 13:03 ` Eli Zaretskii
0 siblings, 1 reply; 26+ messages in thread
From: Kai Ma @ 2024-06-10 12:34 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 71454
[-- Attachment #1: Type: text/plain, Size: 1778 bytes --]
> On Jun 10, 2024, at 13:58, Eli Zaretskii <eliz@gnu.org> wrote:
>
>> From: Kai Ma <justksqsf@gmail.com>
>> Date: Sun, 9 Jun 2024 20:56:47 +0200
>>
>> I have currently (length (font-family-list)) = 582 font families
>> installed. And whenever I input some ununsual characters, Emacs will
>> freeze for seconds until I am able to do anything else. Worse, the
>> freeze delay for each character will add up. And whenver the face
>> changes (including hl-line-mode), or I switched to another buffer for
>> some time, there will be a delay again.
>
> FTR, I have 553 font families, and I see no significant delay when
> pasting the characters you show.
>
>> I'm pretty sure this is due to font selection, because Emacs won't
>> freeze if I configure manually the fallback fonts for each 'exotic'
>> script I encounter.
>
> If this is the case, please tell the details: which fonts you need to
> configure manually to eliminate the delay.
I currently use the following config:
(set-fontset-font t 'han "PingFang TC")
(set-fontset-font t 'kana "PingFang TC")
(set-fontset-font t 'kanbun "PingFang TC")
(set-fontset-font t 'hangul "PingFang TC")
(set-fontset-font t 'cjk-misc "PingFang TC")
(set-fontset-font t 'unicode "PingFang TC" nil 'append)
(set-fontset-font t 'unicode (font-spec :family "Apple Color Emoji") nil 'prepend)
(dolist (thfont '("TH-Feon" "TH-Sy-P0" "TH-Sy-P2" "TH-Sy-P16" "TH-Tshyn-P0"))
(set-fontset-font t 'unicode thfont nil 'append))
PingFang TC and Apple Color Emoji are built into macOS, and TH-* fonts are from the Internet to cover a majority of the Unicode code points.
For example, 〡〢〣〤〥〦〨〩〸〹〺 belongs to cjk-misc script, and I have to specify a font for it to avoid delays.
[-- Attachment #2: Type: text/html, Size: 2440 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-06-10 12:34 ` Kai Ma
@ 2024-06-10 13:03 ` Eli Zaretskii
0 siblings, 0 replies; 26+ messages in thread
From: Eli Zaretskii @ 2024-06-10 13:03 UTC (permalink / raw)
To: Kai Ma; +Cc: 71454
> From: Kai Ma <justksqsf@gmail.com>
> Date: Mon, 10 Jun 2024 14:34:42 +0200
> Cc: 71454@debbugs.gnu.org
>
> I currently use the following config:
>
> (set-fontset-font t 'han "PingFang TC")
> (set-fontset-font t 'kana "PingFang TC")
> (set-fontset-font t 'kanbun "PingFang TC")
> (set-fontset-font t 'hangul "PingFang TC")
> (set-fontset-font t 'cjk-misc "PingFang TC")
> (set-fontset-font t 'unicode "PingFang TC" nil 'append)
> (set-fontset-font t 'unicode (font-spec :family "Apple Color Emoji") nil 'prepend)
> (dolist (thfont '("TH-Feon" "TH-Sy-P0" "TH-Sy-P2" "TH-Sy-P16" "TH-Tshyn-P0"))
> (set-fontset-font t 'unicode thfont nil 'append))
>
> PingFang TC and Apple Color Emoji are built into macOS, and TH-* fonts are from the Internet to cover a
> majority of the Unicode code points.
>
> For example, 〡〢〣〤〥〦〨〩〸〹〺 belongs to cjk-misc script, and I have to specify a font for it to avoid
> delays.
FWIW, I get instantaneous display when I copy/paste that text into an
"emacs -Q" I just started, even though I have no fonts for the last 3
characters (which means Emacs searches all the fonts installed on the
system).
^ permalink raw reply [flat|nested] 26+ messages in thread
[parent not found: <22612F93-FC37-48E8-8137-E9FF6F5B3A0D@gmail.com>]
* bug#71454: 30.0.50; Performance issues with font selection
[not found] ` <22612F93-FC37-48E8-8137-E9FF6F5B3A0D@gmail.com>
@ 2024-09-27 6:32 ` Eli Zaretskii
2024-09-27 7:51 ` Kai Ma
2024-09-28 3:36 ` Gerd Möllmann
0 siblings, 2 replies; 26+ messages in thread
From: Eli Zaretskii @ 2024-09-27 6:32 UTC (permalink / raw)
To: Kai Ma, Alan Third, Po Lu, Gerd Möllmann; +Cc: 71454
> From: Kai Ma <justksqsf@gmail.com>
> Date: Fri, 27 Sep 2024 00:42:04 +0200
>
> I got back to this problem today and have some initial ideas.
>
> I did some profiling and the profiler clearly shows that most CPU time was in macfont_list and CTFontDescriptorCreateMatchingFontDescriptors. (screenshot attached below) So yes, it’s a Mac-only problem.
>
> macfont_list will call CTFontDescriptorCreateMatchingFontDescriptors for n times, where n is the number of installed fonts. It seems CTFontDescriptorCreateMatchingFontDescriptors is very expensive, and we should minimize the use of it.
>
> I did a quick proof-of-concept patch (attached) that removes the outer loop (utilizing CTFontDescriptorCreateMatchingFontDescriptors itself to search for fonts). And now I no longer experience long delays. It’s not complete as I haven’t adapted & incorporated mac_font_create_preferred_family_for_attributes yet.
>
> I don’t see noticeable font differences after the change on the files I’m working on. I would like to gather some feedback from the more experienced on whether this is a promising solution or not. If it is, I will refine it into a formal patch.
Thanks. I'm adding a few people in the hope that they could comment
on the patch, or maybe try it and provide feedback.
> > I have currently (length (font-family-list)) = 582 font families
> > installed. And whenever I input some ununsual characters, Emacs will
> > freeze for seconds until I am able to do anything else. Worse, the
> > freeze delay for each character will add up. And whenver the face
> > changes (including hl-line-mode), or I switched to another buffer for
> > some time, there will be a delay again.
This part, about _any_ unusual characters causing a significant delay,
seems to imply that the default fontset is not set up correctly on
your system (or maybe in general on macOS), or perhaps that the way
the fontsets are used on macOS is very different from other systems.
For starters, are the fonts that Emacs selects for the characters you
used for testing different from the fonts defined by fontset-default
for those characters? If so, what happens if you modify
fontset-default (using set-fontset-font) to specify for these
characters the same fonts as what Emacs selects with the default value
of fontset-default? does font selection become much faster (it
should)?
If specifying the precise font in the fontset doesn't speed up font
selection, then something is very wrong with how fontsets are used on
macOS. Emacs comes with the default value of fontset-default that is
already configured for many characters, and the ones you show should
be included. So I'm puzzled why you experience such long delays when
some of those characters are used.
It could also be the matter of selecting the default face's font. For
best results, it should be a font that covers many popular scripts, at
the very least Latin, Cyrillic, and Greek. Judging by the "unusual"
characters you show, it sounds like Latin characters are not well
covered by your default face's font? If so, perhaps choosing a font
with better coverage will make the situation better for you?
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-09-27 6:32 ` Eli Zaretskii
@ 2024-09-27 7:51 ` Kai Ma
2024-09-27 10:29 ` Eli Zaretskii
2024-09-28 3:36 ` Gerd Möllmann
1 sibling, 1 reply; 26+ messages in thread
From: Kai Ma @ 2024-09-27 7:51 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Po Lu, Gerd Möllmann, Alan Third, 71454
[-- Attachment #1: Type: text/plain, Size: 2603 bytes --]
> On Sep 27, 2024, at 08:32, Eli Zaretskii <eliz@gnu.org> wrote:
>
>>> I have currently (length (font-family-list)) = 582 font families
>>> installed. And whenever I input some ununsual characters, Emacs will
>>> freeze for seconds until I am able to do anything else. Worse, the
>>> freeze delay for each character will add up. And whenver the face
>>> changes (including hl-line-mode), or I switched to another buffer for
>>> some time, there will be a delay again.
>
> This part, about _any_ unusual characters causing a significant delay,
> seems to imply that the default fontset is not set up correctly on
> your system (or maybe in general on macOS), or perhaps that the way
> the fontsets are used on macOS is very different from other systems.
> For starters, are the fonts that Emacs selects for the characters you
> used for testing different from the fonts defined by fontset-default
> for those characters? If so, what happens if you modify
> fontset-default (using set-fontset-font) to specify for these
> characters the same fonts as what Emacs selects with the default value
> of fontset-default? does font selection become much faster (it
> should)?
Yes, if I manually set the font, it becomes instant.
> If specifying the precise font in the fontset doesn't speed up font
> selection, then something is very wrong with how fontsets are used on
> macOS. Emacs comes with the default value of fontset-default that is
> already configured for many characters, and the ones you show should
> be included. So I'm puzzled why you experience such long delays when
> some of those characters are used.
>
> It could also be the matter of selecting the default face's font. For
> best results, it should be a font that covers many popular scripts, at
> the very least Latin, Cyrillic, and Greek. Judging by the "unusual"
> characters you show, it sounds like Latin characters are not well
> covered by your default face's font? If so, perhaps choosing a font
> with better coverage will make the situation better for you?
It would not eliminate the problem though. I’m editing a file with new emojis in Unicode 16 (released recently in September) and the emojis are glyphless currently. I experience unbearable delays whenever such glyphs are visible.
Based on the profiling, my guess is that CTFontDescriptorCreateMatchingFontDescriptors is doing a linear search internally (it probably didn’t just pick the specified by the font family?), so macfont_list is accidentally O(n^2). This (if true) should explain why it’s so slow.
[-- Attachment #2: Type: text/html, Size: 20271 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-09-27 7:51 ` Kai Ma
@ 2024-09-27 10:29 ` Eli Zaretskii
0 siblings, 0 replies; 26+ messages in thread
From: Eli Zaretskii @ 2024-09-27 10:29 UTC (permalink / raw)
To: Kai Ma; +Cc: luangruo, gerd.moellmann, alan, 71454
> From: Kai Ma <justksqsf@gmail.com>
> Date: Fri, 27 Sep 2024 09:51:06 +0200
> Cc: Alan Third <alan@idiocy.org>,
> Po Lu <luangruo@yahoo.com>,
> Gerd Möllmann <gerd.moellmann@gmail.com>,
> 71454@debbugs.gnu.org
>
> This part, about _any_ unusual characters causing a significant delay,
> seems to imply that the default fontset is not set up correctly on
> your system (or maybe in general on macOS), or perhaps that the way
> the fontsets are used on macOS is very different from other systems.
> For starters, are the fonts that Emacs selects for the characters you
> used for testing different from the fonts defined by fontset-default
> for those characters? If so, what happens if you modify
> fontset-default (using set-fontset-font) to specify for these
> characters the same fonts as what Emacs selects with the default value
> of fontset-default? does font selection become much faster (it
> should)?
>
> Yes, if I manually set the font, it becomes instant.
Thanks, so it means finding a font that matches the default font's
spec is indeed slow on your system.
I wonder if this is a general issue with macOS, or just with the
version and/or configuration you are running.
> It could also be the matter of selecting the default face's font. For
> best results, it should be a font that covers many popular scripts, at
> the very least Latin, Cyrillic, and Greek. Judging by the "unusual"
> characters you show, it sounds like Latin characters are not well
> covered by your default face's font? If so, perhaps choosing a font
> with better coverage will make the situation better for you?
>
> It would not eliminate the problem though.
I didn't mean that it will. However, being able to display more
characters without delays is a Good Thing regardless.
> Based on the profiling, my guess is that CTFontDescriptorCreateMatchingFontDescriptors is doing a linear
> search internally (it probably didn’t just pick the specified by the font family?), so macfont_list is accidentally O
> (n^2). This (if true) should explain why it’s so slow.
Yes, you said that in your original report.
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-09-27 6:32 ` Eli Zaretskii
2024-09-27 7:51 ` Kai Ma
@ 2024-09-28 3:36 ` Gerd Möllmann
2024-10-12 11:20 ` Eli Zaretskii
1 sibling, 1 reply; 26+ messages in thread
From: Gerd Möllmann @ 2024-09-28 3:36 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Po Lu, Kai Ma, 71454, Alan Third, YAMAMOTO Mitsuharu
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Kai Ma <justksqsf@gmail.com>
>> Date: Fri, 27 Sep 2024 00:42:04 +0200
>>
>> I got back to this problem today and have some initial ideas.
>>
>> I did some profiling and the profiler clearly shows that most CPU
>> time was in macfont_list and
>> CTFontDescriptorCreateMatchingFontDescriptors. (screenshot attached
>> below) So yes, it’s a Mac-only problem.
>>
>> macfont_list will call CTFontDescriptorCreateMatchingFontDescriptors
>> for n times, where n is the number of installed fonts. It seems
>> CTFontDescriptorCreateMatchingFontDescriptors is very expensive, and
>> we should minimize the use of it.
>>
>> I did a quick proof-of-concept patch (attached) that removes the
>> outer loop (utilizing CTFontDescriptorCreateMatchingFontDescriptors
>> itself to search for fonts). And now I no longer experience long
>> delays. It’s not complete as I haven’t adapted & incorporated
>> mac_font_create_preferred_family_for_attributes yet.
>>
>> I don’t see noticeable font differences after the change on the
>> files I’m working on. I would like to gather some feedback from the
>> more experienced on whether this is a promising solution or not. If
>> it is, I will refine it into a formal patch.
>
> Thanks. I'm adding a few people in the hope that they could comment
> on the patch, or maybe try it and provide feedback.
I haven't tried the patch because I can't reproduce the problem and I
don't use much beyond Latin-1 so I think chances are low that I'd see
anyting breaking with the patch.
But looking at the patch, which mostly removes stuff from macfont_list,
I wonder if/how that can be semeantically equalivalent to the existing
code.
Just saying, I'm definitely not an expert in this area.
Adding YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>, the original
author.
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-09-28 3:36 ` Gerd Möllmann
@ 2024-10-12 11:20 ` Eli Zaretskii
2024-10-15 20:34 ` Kai Ma
0 siblings, 1 reply; 26+ messages in thread
From: Eli Zaretskii @ 2024-10-12 11:20 UTC (permalink / raw)
To: Gerd Möllmann, mituharu; +Cc: luangruo, justksqsf, 71454, alan
Ping!
> From: Gerd Möllmann <gerd.moellmann@gmail.com>
> Cc: Kai Ma <justksqsf@gmail.com>, Alan Third <alan@idiocy.org>, Po Lu
> <luangruo@yahoo.com>, 71454@debbugs.gnu.org, YAMAMOTO Mitsuharu
> <mituharu@math.s.chiba-u.ac.jp>
> Date: Sat, 28 Sep 2024 05:36:32 +0200
>
> Eli Zaretskii <eliz@gnu.org> writes:
>
> >> From: Kai Ma <justksqsf@gmail.com>
> >> Date: Fri, 27 Sep 2024 00:42:04 +0200
> >>
> >> I got back to this problem today and have some initial ideas.
> >>
> >> I did some profiling and the profiler clearly shows that most CPU
> >> time was in macfont_list and
> >> CTFontDescriptorCreateMatchingFontDescriptors. (screenshot attached
> >> below) So yes, it’s a Mac-only problem.
> >>
> >> macfont_list will call CTFontDescriptorCreateMatchingFontDescriptors
> >> for n times, where n is the number of installed fonts. It seems
> >> CTFontDescriptorCreateMatchingFontDescriptors is very expensive, and
> >> we should minimize the use of it.
> >>
> >> I did a quick proof-of-concept patch (attached) that removes the
> >> outer loop (utilizing CTFontDescriptorCreateMatchingFontDescriptors
> >> itself to search for fonts). And now I no longer experience long
> >> delays. It’s not complete as I haven’t adapted & incorporated
> >> mac_font_create_preferred_family_for_attributes yet.
> >>
> >> I don’t see noticeable font differences after the change on the
> >> files I’m working on. I would like to gather some feedback from the
> >> more experienced on whether this is a promising solution or not. If
> >> it is, I will refine it into a formal patch.
> >
> > Thanks. I'm adding a few people in the hope that they could comment
> > on the patch, or maybe try it and provide feedback.
>
> I haven't tried the patch because I can't reproduce the problem and I
> don't use much beyond Latin-1 so I think chances are low that I'd see
> anyting breaking with the patch.
>
> But looking at the patch, which mostly removes stuff from macfont_list,
> I wonder if/how that can be semeantically equalivalent to the existing
> code.
>
> Just saying, I'm definitely not an expert in this area.
>
> Adding YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>, the original
> author.
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#71454: 30.0.50; Performance issues with font selection
2024-10-12 11:20 ` Eli Zaretskii
@ 2024-10-15 20:34 ` Kai Ma
0 siblings, 0 replies; 26+ messages in thread
From: Kai Ma @ 2024-10-15 20:34 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Gerd Möllmann, luangruo, alan, 71454, mituharu
[-- Attachment #1: Type: text/plain, Size: 217 bytes --]
I’ve been personally using my change for some while and I didn’t notice any regression (only for my use cases of course). Attached is the final patch. Hopefully it can encourage more NSport users to test it.
[-- Attachment #2: 0001-Improve-the-performance-of-font-selection-on-macOS.patch --]
[-- Type: application/octet-stream, Size: 17227 bytes --]
From 4c6d678848e80538dd6d284e4f0a05c3bec55d07 Mon Sep 17 00:00:00 2001
From: Kai Ma <justksqsf@gmail.com>
Date: Fri, 27 Sep 2024 00:16:22 +0200
Subject: [PATCH] Improve the performance of font selection on macOS
No longer test font families one by one, which made font selection
needlessly slow (Bug#71454).
* src/macfont.m (macfont_list): Change.
---
src/macfont.m | 367 ++++++++++++++++++++++----------------------------
1 file changed, 162 insertions(+), 205 deletions(-)
diff --git a/src/macfont.m b/src/macfont.m
index ccf691479b8..bce0a8ed79d 100644
--- a/src/macfont.m
+++ b/src/macfont.m
@@ -2275,26 +2275,23 @@ static int macfont_variation_glyphs (struct font *, int c,
macfont_list (struct frame *f, Lisp_Object spec)
{
Lisp_Object val = Qnil, family, extra;
- int i, n;
- CFStringRef family_name = NULL;
+ int n, i;
CFMutableDictionaryRef attributes = NULL, traits;
Lisp_Object chars = Qnil;
int spacing = -1;
CTFontSymbolicTraits synth_sym_traits = 0;
- CFArrayRef families;
- CFIndex families_count;
CFCharacterSetRef charset = NULL;
CFArrayRef languages = NULL;
+ CTFontDescriptorRef pat_desc;
+ CFArrayRef descs;
+ CFIndex descs_count;
+ CFMutableArrayRef filtered_descs, traits_array;
+ Lisp_Object entity;
+ CFStringRef pref_family;
block_input ();
family = AREF (spec, FONT_FAMILY_INDEX);
- if (! NILP (family))
- {
- family_name = macfont_create_family_with_symbol (family);
- if (family_name == NULL)
- goto finish;
- }
attributes = macfont_create_attributes_with_spec (spec);
if (! attributes)
@@ -2335,55 +2332,6 @@ static int macfont_variation_glyphs (struct font *, int c,
synth_sym_traits |= kCTFontTraitMonoSpace;
}
- /* Create array of families. */
- if (family_name)
- families = CFArrayCreate (NULL, (const void **) &family_name,
- 1, &kCFTypeArrayCallBacks);
- else
- {
- CFStringRef pref_family;
- CFIndex families_count, pref_family_index = -1;
-
- families = macfont_copy_available_families_cache ();
- if (families == NULL)
- goto err;
-
- families_count = CFArrayGetCount (families);
-
- /* Move preferred family to the front if exists. */
- pref_family =
- mac_font_create_preferred_family_for_attributes (attributes);
- if (pref_family)
- {
- pref_family_index =
- CFArrayGetFirstIndexOfValue (families,
- CFRangeMake (0, families_count),
- pref_family);
- CFRelease (pref_family);
- }
- if (pref_family_index > 0)
- {
- CFMutableArrayRef mutable_families =
- CFArrayCreateMutable (NULL, families_count, &kCFTypeArrayCallBacks);
-
- if (mutable_families)
- {
- CFArrayAppendValue (mutable_families,
- CFArrayGetValueAtIndex (families,
- pref_family_index));
- CFArrayAppendArray (mutable_families, families,
- CFRangeMake (0, pref_family_index));
- if (pref_family_index + 1 < families_count)
- CFArrayAppendArray (mutable_families, families,
- CFRangeMake (pref_family_index + 1,
- families_count
- - (pref_family_index + 1)));
- CFRelease (families);
- families = mutable_families;
- }
- }
- }
-
charset = CFDictionaryGetValue (attributes, kCTFontCharacterSetAttribute);
if (charset)
{
@@ -2410,172 +2358,182 @@ static int macfont_variation_glyphs (struct font *, int c,
val = Qnil;
extra = AREF (spec, FONT_EXTRA_INDEX);
- families_count = CFArrayGetCount (families);
- for (i = 0; i < families_count; i++)
+
+ pat_desc = CTFontDescriptorCreateWithAttributes (attributes);
+ if (! pat_desc)
+ goto err;
+
+ descs = CTFontDescriptorCreateMatchingFontDescriptors (pat_desc, NULL);
+
+ CFRelease (pat_desc);
+ if (! descs)
+ goto err;
+
+ descs_count = CFArrayGetCount (descs);
+ if (descs_count == 0
+ || !macfont_supports_charset_and_languages_p (CFArrayGetValueAtIndex (descs, 0),
+ charset, chars,
+ languages))
{
- CFStringRef family_name = CFArrayGetValueAtIndex (families, i);
- CTFontDescriptorRef pat_desc;
- CFArrayRef descs;
- CFIndex descs_count;
- CFMutableArrayRef filtered_descs, traits_array;
- Lisp_Object entity;
- int j;
-
- CFDictionarySetValue (attributes, kCTFontFamilyNameAttribute,
- family_name);
- pat_desc = CTFontDescriptorCreateWithAttributes (attributes);
- if (! pat_desc)
- goto err;
+ CFRelease (descs);
+ goto err;
+ }
- /* CTFontDescriptorCreateMatchingFontDescriptors on Mac OS X
- 10.7 returns NULL if pat_desc represents the LastResort font.
- So we use CTFontDescriptorCreateMatchingFontDescriptor (no
- trailing "s") for such a font. */
- if (!CFEqual (family_name, CFSTR ("LastResort")))
- descs = CTFontDescriptorCreateMatchingFontDescriptors (pat_desc, NULL);
- else
- {
- CTFontDescriptorRef lr_desc =
- CTFontDescriptorCreateMatchingFontDescriptor (pat_desc, NULL);
- if (lr_desc)
- {
- descs = CFArrayCreate (NULL, (const void **) &lr_desc, 1,
- &kCFTypeArrayCallBacks);
- CFRelease (lr_desc);
- }
- else
- descs = NULL;
- }
- CFRelease (pat_desc);
- if (! descs)
+ filtered_descs =
+ CFArrayCreateMutable (NULL, descs_count, &kCFTypeArrayCallBacks);
+ traits_array = CFArrayCreateMutable (NULL, descs_count, NULL);
+ for (i = 0; i < descs_count; i++)
+ {
+ CTFontDescriptorRef desc = CFArrayGetValueAtIndex (descs, i);
+ CFDictionaryRef dict;
+ CFNumberRef num;
+ CTFontSymbolicTraits sym_traits;
+
+ dict = CTFontDescriptorCopyAttribute (desc, kCTFontTraitsAttribute);
+ if (dict == NULL)
continue;
- descs_count = CFArrayGetCount (descs);
- if (descs_count == 0
- || !macfont_supports_charset_and_languages_p (CFArrayGetValueAtIndex (descs, 0),
- charset, chars,
- languages))
- {
- CFRelease (descs);
- continue;
- }
+ num = CFDictionaryGetValue (dict, kCTFontSymbolicTrait);
+ CFRelease (dict);
+ if (num == NULL
+ || !cfnumber_get_font_symbolic_traits_value (num, &sym_traits))
+ continue;
+
+ if (spacing >= 0
+ && !(synth_sym_traits & kCTFontTraitMonoSpace)
+ && (((sym_traits & kCTFontTraitMonoSpace) != 0)
+ != (spacing >= FONT_SPACING_MONO)))
+ continue;
+
+ /* Don't use a color bitmap font unless its family is
+ explicitly specified or we're looking for a font for
+ emoji. */
+ if ((sym_traits & kCTFontTraitColorGlyphs)
+ && NILP (family)
+ && !EQ (CDR_SAFE (assq_no_quit (QCscript, AREF (spec, FONT_EXTRA_INDEX))),
+ Qemoji))
+ continue;
- filtered_descs =
- CFArrayCreateMutable (NULL, descs_count, &kCFTypeArrayCallBacks);
- traits_array = CFArrayCreateMutable (NULL, descs_count, NULL);
- for (j = 0; j < descs_count; j++)
+ if (i > 0
+ && !macfont_supports_charset_and_languages_p (desc, charset,
+ chars, languages))
+ continue;
+
+ CFArrayAppendValue (filtered_descs, desc);
+ CFArrayAppendValue (traits_array,
+ (const void *) (uintptr_t) sym_traits);
+ }
+
+ CFRelease (descs);
+ descs = filtered_descs;
+ descs_count = CFArrayGetCount (descs);
+
+ /* Move preferred family to the front if exists. */
+ pref_family = mac_font_create_preferred_family_for_attributes (attributes);
+ if (pref_family)
+ {
+ int pref_family_index = -1;
+ for (i = 0; i < descs_count; i++)
{
- CTFontDescriptorRef desc = CFArrayGetValueAtIndex (descs, j);
- CFDictionaryRef dict;
- CFNumberRef num;
- CTFontSymbolicTraits sym_traits;
+ CTFontDescriptorRef desc = CFArrayGetValueAtIndex (descs, i);
+ CFStringRef family =
+ CTFontDescriptorCopyAttribute (desc, kCTFontFamilyNameAttribute);
- dict = CTFontDescriptorCopyAttribute (desc, kCTFontTraitsAttribute);
- if (dict == NULL)
- continue;
-
- num = CFDictionaryGetValue (dict, kCTFontSymbolicTrait);
- CFRelease (dict);
- if (num == NULL
- || !cfnumber_get_font_symbolic_traits_value (num, &sym_traits))
- continue;
-
- if (spacing >= 0
- && !(synth_sym_traits & kCTFontTraitMonoSpace)
- && (((sym_traits & kCTFontTraitMonoSpace) != 0)
- != (spacing >= FONT_SPACING_MONO)))
- continue;
-
- /* Don't use a color bitmap font unless its family is
- explicitly specified or we're looking for a font for
- emoji. */
- if ((sym_traits & kCTFontTraitColorGlyphs)
- && NILP (family)
- && !EQ (CDR_SAFE (assq_no_quit (QCscript, AREF (spec, FONT_EXTRA_INDEX))),
- Qemoji))
- continue;
-
- if (j > 0
- && !macfont_supports_charset_and_languages_p (desc, charset,
- chars, languages))
- continue;
-
- CFArrayAppendValue (filtered_descs, desc);
- CFArrayAppendValue (traits_array,
- (const void *) (uintptr_t) sym_traits);
+ if (CFStringCompare (family, pref_family, 0) == kCFCompareEqualTo)
+ pref_family_index = i;
}
- CFRelease (descs);
- descs = filtered_descs;
- descs_count = CFArrayGetCount (descs);
+ CFRelease (pref_family);
- for (j = 0; j < descs_count; j++)
+ if (pref_family_index > 0)
{
- CTFontDescriptorRef desc = CFArrayGetValueAtIndex (descs, j);
- CTFontSymbolicTraits sym_traits =
- ((CTFontSymbolicTraits) (uintptr_t)
- CFArrayGetValueAtIndex (traits_array, j));
- CTFontSymbolicTraits mask_min, mask_max, imask, bmask, mmask;
-
- mask_min = ((synth_sym_traits ^ sym_traits)
- & (kCTFontTraitItalic | kCTFontTraitBold));
- if (FONT_SLANT_NUMERIC (spec) < 0)
- mask_min &= ~kCTFontTraitItalic;
- if (FONT_WEIGHT_NUMERIC (spec) < 0)
- mask_min &= ~kCTFontTraitBold;
-
- mask_max = (synth_sym_traits & ~sym_traits);
- /* Synthetic bold does not work for bitmap-only fonts on Mac
- OS X 10.6. */
- if ((mask_min ^ mask_max) & kCTFontTraitBold)
+ CFMutableArrayRef mutable_descs =
+ CFArrayCreateMutable (NULL, descs_count, &kCFTypeArrayCallBacks);
+
+ if (mutable_descs)
{
- CFNumberRef format =
- CTFontDescriptorCopyAttribute (desc, kCTFontFormatAttribute);
+ CFArrayAppendValue (mutable_descs,
+ CFArrayGetValueAtIndex (descs,
+ pref_family_index));
+ CFArrayAppendArray (mutable_descs, descs,
+ CFRangeMake (0, pref_family_index));
+ if (pref_family_index + 1 < descs_count)
+ CFArrayAppendArray (mutable_descs, descs,
+ CFRangeMake (pref_family_index + 1,
+ descs_count
+ - (pref_family_index + 1)));
+ CFRelease (descs);
+ descs = mutable_descs;
+ }
+ }
+ }
- if (format)
- {
- uint32_t format_val;
+ for (i = 0; i < descs_count; i++)
+ {
+ CTFontDescriptorRef desc = CFArrayGetValueAtIndex (descs, i);
+ CTFontSymbolicTraits sym_traits =
+ ((CTFontSymbolicTraits) (uintptr_t)
+ CFArrayGetValueAtIndex (traits_array, i));
+ CTFontSymbolicTraits mask_min, mask_max, imask, bmask, mmask;
+
+ mask_min = ((synth_sym_traits ^ sym_traits)
+ & (kCTFontTraitItalic | kCTFontTraitBold));
+ if (FONT_SLANT_NUMERIC (spec) < 0)
+ mask_min &= ~kCTFontTraitItalic;
+ if (FONT_WEIGHT_NUMERIC (spec) < 0)
+ mask_min &= ~kCTFontTraitBold;
+
+ mask_max = (synth_sym_traits & ~sym_traits);
+ /* Synthetic bold does not work for bitmap-only fonts on Mac
+ OS X 10.6. */
+ if ((mask_min ^ mask_max) & kCTFontTraitBold)
+ {
+ CFNumberRef format =
+ CTFontDescriptorCopyAttribute (desc, kCTFontFormatAttribute);
- if (CFNumberGetValue (format, kCFNumberSInt32Type,
- &format_val)
- && format_val == kCTFontFormatBitmap)
- mask_max &= ~kCTFontTraitBold;
- }
- }
- if (spacing >= 0)
- mask_min |= (mask_max & kCTFontTraitMonoSpace);
-
- for (mmask = (mask_min & kCTFontTraitMonoSpace);
- mmask <= (mask_max & kCTFontTraitMonoSpace);
- mmask += kCTFontTraitMonoSpace)
- for (bmask = (mask_min & kCTFontTraitBold);
- bmask <= (mask_max & kCTFontTraitBold);
- bmask += kCTFontTraitBold)
- for (imask = (mask_min & kCTFontTraitItalic);
- imask <= (mask_max & kCTFontTraitItalic);
- imask += kCTFontTraitItalic)
- {
- CTFontSymbolicTraits synth = (imask | bmask | mmask);
+ if (format)
+ {
+ uint32_t format_val;
- if (synth == 0
- || macfont_closest_traits_index_p (traits_array,
- (sym_traits | synth),
- j))
- {
- entity = macfont_descriptor_entity (desc, extra, synth);
- if (! NILP (entity))
- val = Fcons (entity, val);
- }
- }
+ if (CFNumberGetValue (format, kCFNumberSInt32Type,
+ &format_val)
+ && format_val == kCTFontFormatBitmap)
+ mask_max &= ~kCTFontTraitBold;
+ }
}
+ if (spacing >= 0)
+ mask_min |= (mask_max & kCTFontTraitMonoSpace);
+
+ for (mmask = (mask_min & kCTFontTraitMonoSpace);
+ mmask <= (mask_max & kCTFontTraitMonoSpace);
+ mmask += kCTFontTraitMonoSpace)
+ for (bmask = (mask_min & kCTFontTraitBold);
+ bmask <= (mask_max & kCTFontTraitBold);
+ bmask += kCTFontTraitBold)
+ for (imask = (mask_min & kCTFontTraitItalic);
+ imask <= (mask_max & kCTFontTraitItalic);
+ imask += kCTFontTraitItalic)
+ {
+ CTFontSymbolicTraits synth = (imask | bmask | mmask);
- CFRelease (traits_array);
- CFRelease (descs);
+ if (synth == 0
+ || macfont_closest_traits_index_p (traits_array,
+ (sym_traits | synth),
+ i))
+ {
+ entity = macfont_descriptor_entity (desc, extra, synth);
+ if (! NILP (entity))
+ val = Fcons (entity, val);
+ }
+ }
}
- CFRelease (families);
+ CFRelease (traits_array);
+ CFRelease (descs);
+
val = Fnreverse (val);
goto finish;
+
err:
val = Qnil;
@@ -2584,7 +2542,6 @@ So we use CTFontDescriptorCreateMatchingFontDescriptor (no
if (charset) CFRelease (charset);
if (languages) CFRelease (languages);
if (attributes) CFRelease (attributes);
- if (family_name) CFRelease (family_name);
unblock_input ();
--
2.39.5 (Apple Git-154)
[-- Attachment #3: Type: text/plain, Size: 2368 bytes --]
> On Oct 12, 2024, at 13:20, Eli Zaretskii <eliz@gnu.org> wrote:
>
> Ping!
>
>> From: Gerd Möllmann <gerd.moellmann@gmail.com>
>> Cc: Kai Ma <justksqsf@gmail.com>, Alan Third <alan@idiocy.org>, Po Lu
>> <luangruo@yahoo.com>, 71454@debbugs.gnu.org, YAMAMOTO Mitsuharu
>> <mituharu@math.s.chiba-u.ac.jp>
>> Date: Sat, 28 Sep 2024 05:36:32 +0200
>>
>> Eli Zaretskii <eliz@gnu.org> writes:
>>
>>>> From: Kai Ma <justksqsf@gmail.com>
>>>> Date: Fri, 27 Sep 2024 00:42:04 +0200
>>>>
>>>> I got back to this problem today and have some initial ideas.
>>>>
>>>> I did some profiling and the profiler clearly shows that most CPU
>>>> time was in macfont_list and
>>>> CTFontDescriptorCreateMatchingFontDescriptors. (screenshot attached
>>>> below) So yes, it’s a Mac-only problem.
>>>>
>>>> macfont_list will call CTFontDescriptorCreateMatchingFontDescriptors
>>>> for n times, where n is the number of installed fonts. It seems
>>>> CTFontDescriptorCreateMatchingFontDescriptors is very expensive, and
>>>> we should minimize the use of it.
>>>>
>>>> I did a quick proof-of-concept patch (attached) that removes the
>>>> outer loop (utilizing CTFontDescriptorCreateMatchingFontDescriptors
>>>> itself to search for fonts). And now I no longer experience long
>>>> delays. It’s not complete as I haven’t adapted & incorporated
>>>> mac_font_create_preferred_family_for_attributes yet.
>>>>
>>>> I don’t see noticeable font differences after the change on the
>>>> files I’m working on. I would like to gather some feedback from the
>>>> more experienced on whether this is a promising solution or not. If
>>>> it is, I will refine it into a formal patch.
>>>
>>> Thanks. I'm adding a few people in the hope that they could comment
>>> on the patch, or maybe try it and provide feedback.
>>
>> I haven't tried the patch because I can't reproduce the problem and I
>> don't use much beyond Latin-1 so I think chances are low that I'd see
>> anyting breaking with the patch.
>>
>> But looking at the patch, which mostly removes stuff from macfont_list,
>> I wonder if/how that can be semeantically equalivalent to the existing
>> code.
>>
>> Just saying, I'm definitely not an expert in this area.
>>
>> Adding YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>, the original
>> author.
>>
^ permalink raw reply related [flat|nested] 26+ messages in thread
end of thread, other threads:[~2024-10-15 20:34 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-09 18:56 bug#71454: 30.0.50; Performance issues with font selection Kai Ma
2024-06-09 22:10 ` Jeremy Bryant via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-09 22:17 ` Kai Ma
2024-06-09 22:34 ` Jeremy Bryant via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-10 2:14 ` Kai Ma
2024-06-10 12:04 ` Eli Zaretskii
2024-06-09 23:10 ` Jim Porter
2024-06-10 2:18 ` Kai Ma
2024-06-10 11:53 ` Eli Zaretskii
2024-06-10 16:31 ` Jim Porter
2024-06-10 17:35 ` Eli Zaretskii
2024-06-10 11:55 ` Eli Zaretskii
2024-06-10 12:35 ` Kai Ma
2024-06-10 12:59 ` Eli Zaretskii
2024-06-10 16:42 ` Gerd Möllmann
2024-06-10 17:36 ` Kai Ma
2024-06-10 18:05 ` Gerd Möllmann
2024-06-10 11:58 ` Eli Zaretskii
2024-06-10 12:34 ` Kai Ma
2024-06-10 13:03 ` Eli Zaretskii
[not found] ` <22612F93-FC37-48E8-8137-E9FF6F5B3A0D@gmail.com>
2024-09-27 6:32 ` Eli Zaretskii
2024-09-27 7:51 ` Kai Ma
2024-09-27 10:29 ` Eli Zaretskii
2024-09-28 3:36 ` Gerd Möllmann
2024-10-12 11:20 ` Eli Zaretskii
2024-10-15 20:34 ` Kai Ma
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).