# Re: [NTG-context] XeConTeXt bug report I: strange benchmark

Yue Wang wrote:

> After debugging for half an hour in the morning, finally I know why
> this is so slow on both XeTeX and pdfTeX.
> This problem is not an operating system issue, But a ConTeXt "feature".
>
> in font-mkii, you use the following to define a actual font
> (\definefontlocal and \definefontglobal):
>   {\expandafter\xdef\csname#1\endcsname  % ! ! ! ! not needed in luatex ! ! !
> !
>      {\noexpand\csname#1:\endcsname
>       \noexpand\reactivatefont{\somefontname}{\fontfile}}%
>
> For example, in the previous example, it will define a lot of fonts,
> like \*myzhfont12ptmmexrm*: , is defined as
> \reactivatefont{cmex10}{lmex10}. When define that font, a macro
> \*myzhfont12ptmmexrm* is defined to select the \*myzhfont12ptmmexrm* :
> font.
> \*myzhfont12ptmmexrm* =\csname *myzhfont12ptmmexrm* :\endcsname
> \reactivefont{cmex10}{lmex10}
> TeX then expand your reactivatefont macros to lmex10 at 12.0pt. So the
> \*myzhfont12ptmmexrm*: font will assigned to lmex10 at 12.0pt. This is
> quite right for definition.
>
> However, after switching the font, the problems occurs:
> it tries to call \*myzhfont12ptmmexrm* macro. the macro then expands to
> \csname *myzhfont12ptmmexrm* :\endcsname \reactivefont{cmex10}{lmex10}
> then to
> \*myzhfont12ptmmexrm* :\reactivefont{cmex10}{lmex10}
> and here TeX tries to do the following thing:
> TeX select the font \*myzhfont12ptmmexrm*:, which is lmex10 at 12pt,
> then *changing* into that font environment in order to *typeset*
> \reactivefont.  it then expand the macro of reacitve font, but found
> nothing to typeset...

some of that activation can involve things that set up the font (some
related properties) so the mechanism is kind of generic; at that point
it is not possible to determine what is relevant and what not

changing such things at frst sight might lead to unexpected side effects
later on (as the context history has proven)

although part of the activation code can be disables when defining a
sequence of fonts (as in a massive switch) it would complicate the font
code even more to do so; in mkiv we do need less of that as explained
below (hence the remark 'not needed in luatex')

for instance, we can redefine (for xetex)

\def\updatefontparameters
{\edef\@@fontfeatures{\truefontdata\fontfile    \s!features}%
\edef\@@fontskewchar{\truefontdata\fontfile    \s!skewchar}}

\def\setfontcharacteristics
{%\updatefontparameters % redundant, will go away, faster too
\the\everyfont
\synchronizepatternswithfont}

Which is faster,  but then we also need to make absolutely sure that
xetex only uses opentype fonts (which in turn means that we need to
provide separate typescript files for xetex to make sure that this
happens); this can be significant on a 10 second job with 10K switches,
but less in a complex document that takes 2 minutes to process, or as we

Another option is to make all sizes (\tf*) optional, which then would
force a typeface switch in heads which in turn slows down things at that
end, or you could disable bigmath (that follows the sizes) and then end
up with mails to this list why math does not scale in titles, etc etc

> what's worse, this will occur on every real fonts in the definition.
> So in fact TeX will switching dozens of fonts into the *current* font
> for a "\switchtobodyfont" call, in order to typeset nothing. And
> that's why ConTeXt is so slow on typeface changing.
>
> The solution to this bug (or feature?) is quite easy, just use \font
> to define the \*myzhfont12ptmmexrm*: font, but pay attention not to
> switch the current font to \*myzhfont12ptmmexrm*: . Since it is quite
> slow to switch to dozens of font for one \switchtobodyfont call even
> in Knuth TeX.

You make it sound as all of the font system's features are kind of wrong
and contain oversights ... i'm not going to enter a discussion about the
how and why of the context way of doing things as it is a accumulation
of over 15 years of development and experients and realistic typesetting
situations. We're not that stupid.

In mkii (and to a lesser extent in mkiv) we have to deal with several
situations:

Fonts have 256 chars at most so they cannot cover each language. This
means that when one mixes languages, one also might need multiple fonts.
For instance using two complete different typefaces, one with ec
encoding, another with texnansi encoding and both with different math
fonts also in a different encoding is happing at our end.

As fonts encodings are related to hyphenation, there is a relationship
between a font switch and a language switch i.e. when we're typesetting
in czech it might be that a font switch also results in a patterns
switch due to the fact that patterns relate to fonts. The fact that CJK
does not hyphenate is no reason to remove that feature from the font
system. I know that the latex way of doing things is to replace and
redefine core code for specific purposes, but that's not the way we do
things in context. In my own usage i just accepted the fact that in
order to typeset my own stuff my jobs ran slower because other languages
needed other features to be present.

So, we have encodings, languages, upper/lowercase mappings, font
handling, some math properties, etc. so in practice several bits and
pieces need to be synchronized when we switch a font (not relevant maybe
for cjk but definitely relevant for other scripts). There can even be
weird font related issues that need to be dealt with.

Now, when one uses a typeface (i.e. fontclasses) the actual loading of
the font takes place only once as we assume that one will not redefine a
typeface mid-document. The only things that happening with each
(individual) font switch are these synchronizations.

When switching a typeface, only a few fonts are really defined (loaded)
as tracing shows but some things are set up each time (of course, as we
obey grouping). If you are sure that there are no dependencies (i.e. a
regular title with embedded bold, math, etc) you can use \definefont and
assign that font to the style property of for instance a section head.

The whole system is targeting at situations that we have to deal with at
pragma, and when setting up styles it's no big deal to do that
efficiently with a mix of typefaces and \definefont definitions (using
symbolic FontNames so that encoding etc is nicely dealt with). You
mentioned many font switches in your document, well believe me, some of
the documents we produce have many too and compared to other typesetting
tasks dealing with fonts is not the bottleneck.

Now, in mkiv we have a bit less complex system because we only have one
input encoding (utf i.e. unicode), one font encoding (unicode), and one
math encoding (unicode) and so it has a more optimal code base. As xetex
shares code with pdftex (both use mkii) code, it has the burden of some
overhead not needed if we'd settle on one encoding (although xetex does
handle multiple font encodings). However, that would demand a partial
rewrite of the mkii font subsystem specially for xetex (and eventually
also for the math subsystem) which is currently not on the agenda
(unless i need it in well paid projects).

As i mentioned yesterday, i can disable a few aspects of mkii in xetex
mode, but the gain is not so large and as i don't use xetex on a regular
basis it does not pay off to complicate the code. Simplified math might
make a difference but as lm/gyre open type math is not there yet, i
won't even start looking into it (if at all). The problem is simply that
mkii (or derived xetex upgrades) will not keep up with mkiv anyway. I
don't see much reason for making an advanced mkiv system (which takes
time) and then derive a crippled halfway mkii-mkiv system just for fun
(which is not that much fun actually; okay, if someone comes up with a
project i might refactor bit and pieces).

So, no bugs, nor 'features' but just features cq. functionality that is
the result of over 15 years of supporting everything that came along.
Reading of the font related docs that come with context probably reveal
much of this anyway.

Context deals (and is made for) mixed languages, fonts, etc etc and it
will stay that way. We will not optimize for specific usage. Also, in
practice font switching only part of the game and other typesetting
tasks might take much more time (esp when one sets up complex page
layouts).

Hans

ps. in mkiv we gain time at the definition end but then loose it at the
processing end because there we want to do more clever things that take
time anyway

-----------------------------------------------------------------
Ridderstraat 27 | 8061 GH Hasselt | The Netherlands
tel: 038 477 53 69 | fax: 038 477 53 74 | www.pragma-ade.com
| www.pragma-pod.nl
-----------------------------------------------------------------
___________________________________________________________________________________