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: Eli Zaretskii
Subject: bug#21028: Performance regression in revision af1a69f4d17a482c359d98c00ef86fac835b5fac (Apr 2014).
Date: Wed, 15 Mar 2017 17:36:12 +0200

> Cc: 21028@debbugs.gnu.org
> From: Clément Pit--Claudel <clement.pitclaudel@live.com>
> Date: Tue, 14 Mar 2017 15:35:01 -0400
> 
> > 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?

The problem here is that opening a font and looking up a character is
very expensive, certainly when there are hundreds of fonts installed.
So Emacs filters the fonts according to the scripts they claim to
support, and only opens those which appear to be valid candidates for
the script of the character it needs to display.  By using 'unicode as
the script when you set up your fontset, you actually trip Emacs by
telling it to try this font for every character it needs to display.
You should instead specify the scripts which the fonts supports well.
And for the default font (i.e. the font of the default face) I think
you don't have to put it into the fontset at all, just specify it as
the default font (via default-frame-alist, for example).

> 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 (≠, ≤, …).

That shouldn't be a problem in Emacs 25: it by default uses the
default face's font for any punctuation and symbol characters for
which the font has glyphs, even if the fontset specifies a different
font for punctuation and symbol blocks.

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

So using more accurate scripts gives a major improvement.  Good.

> For me specifying the registry doesn't seem to do anything

That could sometimes be the case, but I have found that in some cases
omitting the registry for characters beyond Latin-1 can be a major
setback.  So I recommend to always use it.

> The following uses *Ubuntu Mono* (?!) and XITS Math, and is very slow

I'm guessing that Ubuntu Mono is your system's default font which
Emacs picks up.  The fontset-default specifies fallbacks, it doesn't
affect the default font.

I'm not sure what exactly do you want to happen, because I don't
understand why you need 2 monospaced fonts in your setup.  So I cannot
yet suggest how to set your fonts for them to do what you want.  But
see below for some proposals.

> 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 "√"?

See above: that's a feature of Emacs 25 -- it by default uses the
default face's font for punctuation and symbol characters.  You can
use use-default-font-for-symbols, new in Emacs 25.2, to disable this
feature and go by the fontsets instead, but I believe the default
produces better results in most cases.

> > (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 than 'latin, 'greek, and 'cyrillic: I want "any character 
> that 
> this font supports".

Given that symbols and punctuation characters already use that font,
why do you need more than that, and in what Unicode blocks?

You can use a font utility, such as Fontforge, to see which blocks the
font supports, and how many characters from each block it can display.
My conclusion from looking at Ubuntu Mono is that the above 3 scripts
are the only ones it supports well; the rest are not covered well at
all.  You can, of course, add more scripts if you need them, but the
downside will be that some of those scripts will be displayed by a mix
of more than one font, which I think will make the display ugly.
Moreover, Emacs cannot compose glyphs that come from different fonts,
so you will sometimes see decomposed display if you request a font for
scripts where its support is incomplete.  I think this is an important
factor for users of prettify-symbols-mode in particular.

> > (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?

Not necessarily: you could specify the full range of codepoints from
the Emoji block, even if some of them are not yet available.

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

Then set it up by copying the default setup from fontset.el, as that
setup is based on a lot of thought and careful testing on several
systems.

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

No, I'm saying that you have no reason to repeat the fallback fonts in
any fontset but fontset-default.  The default font should be
customized differently, not through fontsets.

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

That's again because you use fontsets for the default face's font.
You should instead use default-frame-alist for that, and leave
fontsets only for when a character might be unavailable in the default
font.

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

Well, maybe with the new insights you have now, you can recommend them
better setups which don't use 'unicode'.





reply via email to

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