bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#21028: Performance regression in revision af1a69f4d17a482c359d98c00e


From: Clément Pit--Claudel
Subject: bug#21028: Performance regression in revision af1a69f4d17a482c359d98c00ef86fac835b5fac (Apr 2014).
Date: Tue, 14 Mar 2017 15:35:01 -0400
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.7.0

On 2017-03-14 11:45, Eli Zaretskii wrote:
> I checked: all the fonts you use as the default -- Noto Sans, Fira 
> Sans, Ubuntu Mono -- all of them basically support only Latin,
> Greek, and Cyrillic blocks, and very little else.  By contrast, the
> above fontset specification claims that they support the entire
> Unicode range of characters, which causes Emacs waste cycles trying
> to use these fonts for display of characters they don't support.

Is there a way to tell Emacs to use them for everything they support? For 
example, Ubuntu Mono supports box-drawing characters (so I could add that 
range), but it also supports U+2202 "partial diff", U+2206 "Delta", U+2211 
"summation", and U+222B "integral", and a few other symbols (≠, ≤, …).

> In addition, the font-spec doesn't specify the registry of the
> fonts, leaving that to the default, which IME is inadequate.  So
> please try the following, and see if you get any significant
> speedup:

I do :)  See timings below:

# With your patch
$ time master/src/emacs -Q --eval "(progn (set-fontset-font \"fontset-default\" 
'latin '(\"Noto Sans\" . \"iso10646-1\") nil) (set-fontset-font 
\"fontset-default\" 'unicode '(\"Symbola\" . \"iso10646-1\") nil 'append) 
(dotimes (_ 5000) (insert (make-string 20 8658) \"\n\")) (goto-char 
(point-min)) (sit-for 0) (condition-case nil (while t (scroll-up) (sit-for 0)) 
(error nil)) (run-with-idle-timer 0 nil #'kill-emacs))"
real    0m0.532s
user    0m0.404s
sys     0m0.024s

# Without your patch
$ time 25.1/src/emacs -Q --eval "(progn (set-fontset-font \"fontset-default\" 
'latin '(\"Noto Sans\" . \"iso10646-1\") nil) (set-fontset-font 
\"fontset-default\" 'unicode '(\"Symbola\" . \"iso10646-1\") nil 'append) 
(dotimes (_ 5000) (insert (make-string 20 8658) \"\n\")) (goto-char 
(point-min)) (sit-for 0) (condition-case nil (while t (scroll-up) (sit-for 0)) 
(error nil)) (run-with-idle-timer 0 nil #'kill-emacs))"
real    0m0.577s
user    0m0.392s
sys     0m0.020s

And more experiments:

# With just 'latin (no registry) on stock 25.1:
$ time 25.1/src/emacs -Q --eval "(progn (set-fontset-font \"fontset-default\" 
'latin \"Noto Sans\" nil) (set-fontset-font \"fontset-default\" 'unicode 
\"Symbola\" nil 'append) (dotimes (_ 5000) (insert (make-string 20 8658) 
\"\n\")) (goto-char (point-min)) (sit-for 0) (condition-case nil (while t 
(scroll-up) (sit-for 0)) (error nil)) (run-with-idle-timer 0 nil #'kill-emacs))"
real    0m0.587s
user    0m0.416s
sys     0m0.012s

# With just the registries (and 'unicode instead of 'latin) on stock 25.1
$ time 25.1/src/emacs -Q --eval "(progn (set-fontset-font \"fontset-default\" 
'unicode '(\"Noto Sans\" . \"iso10646-1\") nil) (set-fontset-font 
\"fontset-default\" 'unicode '(\"Symbola\" . \"iso10646-1\") nil 'append) 
(dotimes (_ 5000) (insert (make-string 20 8658) \"\n\")) (goto-char 
(point-min)) (sit-for 0) (condition-case nil (while t (scroll-up) (sit-for 0)) 
(error nil)) (run-with-idle-timer 0 nil #'kill-emacs))"
real    0m42.250s
user    0m22.148s
sys     0m6.220s

# With 'unicode and inhibit-compacting-font-caches on stock 25.1:
$ time 25.1/src/emacs -Q --eval "(progn (setq inhibit-compacting-font-caches t) 
(set-fontset-font \"fontset-default\" 'unicode '(\"Noto Sans\" . 
\"iso10646-1\") nil) (set-fontset-font \"fontset-default\" 'unicode 
'(\"Symbola\" . \"iso10646-1\") nil 'append) (dotimes (_ 5000) (insert 
(make-string 20 8658) \"\n\")) (goto-char (point-min)) (sit-for 0) 
(condition-case nil (while t (scroll-up) (sit-for 0)) (error nil)) 
(run-with-idle-timer 0 nil #'kill-emacs))"
real    0m42.105s
user    0m22.340s
sys     0m6.124s

> Other than that, I'm sorry to say that I couldn't reproduce any of
> the slowdowns you mention in this bug report and in the referenced
> issues. In each of the recipes I tried, the slowdown disappears
> either if I set inhibit-compacting-font-caches (which you said
> doesn't affect your use cases) or if I define the fontset correctly,
> like specify a registry for a font or the scripts it really supports.
> 
For me specifying the registry doesn't seem to do anything, but restricting the 
font to 'latin does.  Is that example right though?  On my machine, running the 
code above gives me an Emacs that uses Ubuntu Mono and Symbola, not Noto Sans.  
I need to use "fontset-startup" for the font to be taken into account.

To clarify, the following uses Noto Sans and XITS Math, and is very slow:

$ time 25.1/src/emacs -Q --eval "(progn (set-fontset-font \"fontset-startup\" 
'unicode \"Noto Sans\" nil) (set-fontset-font \"fontset-startup\" 'unicode 
\"XITS Math\" nil 'append) (dotimes (_ 5000) (insert (make-string 20 8658) 
\"\n\")) (goto-char (point-min)) (sit-for 0) (condition-case nil (while t 
(scroll-up) (sit-for 0)) (error nil)) (run-with-idle-timer 0 nil #'kill-emacs))"

The following uses *Ubuntu Mono* (?!) and XITS Math, and is very slow
$ time 25.1/src/emacs -Q --eval "(progn (set-fontset-font \"fontset-default\" 
'unicode \"Noto Sans\" nil) (set-fontset-font \"fontset-default\" 'unicode 
\"XITS Math\" nil 'append) (dotimes (_ 5000) (insert (make-string 20 8658) 
\"\n\")) (goto-char (point-min)) (sit-for 0) (condition-case nil (while t 
(scroll-up) (sit-for 0)) (error nil)) (run-with-idle-timer 0 nil #'kill-emacs))"

The following uses Noto Sans and XITS Math, and is very fast:
$ time 25.1/src/emacs -Q --eval "(progn (set-fontset-font \"fontset-startup\" 
'latin \"Noto Sans\" nil) (set-fontset-font \"fontset-startup\" 'unicode \"XITS 
Math\" nil 'append) (dotimes (_ 5000) (insert (make-string 20 8658) \"\n\")) 
(goto-char (point-min)) (sit-for 0) (condition-case nil (while t (scroll-up) 
(sit-for 0)) (error nil)) (run-with-idle-timer 0 nil #'kill-emacs))"

I'm a bit confused, though: the restriction to latin still allows Emacs to use 
Noto Sans for characters like "⅔", "≠", and "√"?

> It's possible that these factors somehow have a much more significant
> effect on your system, I don't know why.  Perhaps you have an awful
> lot of fonts installed?  What does the following yield when
> evaluated:
> 
> (length (x-list-fonts "-*-*-*-r-*-*-*-*-*-*-*-*-iso10646-1"))

I get 874.

> Allow me a few comments on your real-life setup, they could be 
> relevant even if they don't resolve the slow display with stock
> Emacs:
>
> All of the above specs lack a proper :registry value, which should
> be 'iso10646-1.

Thanks.

> (set-fontset-font fontset 'unicode base-spec nil)
> 
> This should only specify 'latin, 'greek, and 'cyrillic (one such
> line for each of them), as 'unicode is a blatant lie.

But I want more tha 'latin, 'greek, and 'cyrillic: I want "any character that 
this font supports".

> (set-fontset-font fontset 'unicode emoji-spec nil 'append)
> 
> It is better o have a definitive list of codepoint ranges here,
> since again 'unicode is not what you want.  Once you have the ranges,
> you can use 'prepend, which will speed up things a bit more, because
> Emacs won't need to go through all the fonts you don't want to see.

Possibly — but this will break next time the font is updated with more Emoji, 
right?

> (set-fontset-font fontset 'unicode fallback-spec nil 'append)
> 
> This you shouldn't need doing, as Symbola is already in the default 
> fontset, and set up according to the characters where it shines.

I used a variant of Symbola, not Symbola itself.

> (dolist (cjk-block '((#x3000 . #x303F) (#x3040 . #x309F) (#x30A0 .
> #x30FF) (#x3400 . #x4DFF) (#x4E00 . #x9FFF) (#xF900 . #xFAFF) 
> (#x20000 . #x2A6DF) (#x2A700 . #x2B73F) (#x2B740 . #x2B81F) (#x2B820
> . #x2CEAF) (#x2F800 . #x2FA1F))) (set-fontset-font fontset cjk-block
> cjk-spec nil 'append))))
> 
> This should use 'prepend, not 'append, IMO.

Thanks, good point!

> One more comment: any reasons why you set this up for all the 
> fontsets, not just for fontset-default?  AFAIU, doing these changes
> in all of the fonts might slow down things even more, for no good
> reason, because fontset-default is the fallback for all the other
> fontsets anyway, so anything you set up in it will be in effect for
> any other fontset.

I'm not sure I understand.  Are you saying that e.g. running the following 
should show display a *scratch* buffer in Noto Sans?

$ 25.1/src/emacs -Q --eval "(set-fontset-font \"fontset-default\" 'latin \"Noto 
Sans\" nil)"

It doesn't for me.  I need to set fontset-startup instead.

$ 25.1/src/emacs -Q --eval "(set-fontset-font \"fontset-startup\" 'latin \"Noto 
Sans\" nil)"

But then I run into trouble when I change the font size (with 
set-face-attribute), because that creates new fontsets.

>> The problem gets regularly mentioned elsewhere (when I opened this
>> bug I linked to https://github.com/purcell/emacs.d/issues/273 "when
>> I first try to input some chinese characters, it's very slow to
>> moving [...] especially use C-n, C-p, emacs will hang for about 1~2
>> seconds.";
> 
> The slowdown in that example disappears for me once I set 
> inhibit-compacting-font-caches non-nil.  So the factors at work in 
> that example on my system are somehow different from the factors on 
> your system (unless you will tell that
> inhibit-compacting-font-caches solves the problem for you as well in
> that case).

For me that example is fast in all configurations: the problem I ran into with 
CJK scripts was 2 years ago, and I haven't managed to reproduce it.

> Can you ask some of those people to show their fontset setup?  I'd 
> like to know how different they are from your setup.

They essentially use this:

(dolist (ft (fontset-list))
  (set-fontset-font ft 'unicode (font-spec :name "YOUR-USUAL-FONT"))
  (set-fontset-font ft 'unicode (font-spec :name "Symbola") nil 'append))

because that's what I recommend (that's the only one that I've found to work 
reliably: not specifying 'unicode uses Symbola too often, not looping on the 
fontsets causes issues when changing font sizes, and not specifying Symbola 
sometimes falls back to other fonts).  It used to work great in Emacs 24.3, 
which was the default on Ubuntu for a while (and still is for the long-term 
support release)

> Btw, I'm still trying to understand the significance of the proposed 
> patch, although it's hard without a clear-cut test case.

Thanks for your help!
Clément.

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]