musings-speed.tex /size: 28 Kb    last modification: 2024-01-16 10:21
1% language=us runpath=texruns:manuals/musings
2
3% musical timestamp: listening to FLUX (jazz trio) in Januari 2023
4
5\startcomponent musings-speed
6
7\environment musings-style
8
9\startchapter[title={Speeding up \TEX}]
10
11\startsection[title={Introduction}]
12
13Recently a couple of cordless phones that I use gave up as soon as I used them
14for a minute or so. The first time that happened I figured that after all these
15years the batteries had gone bad and after some testing I decided to replace
16them. I got some of these high end batteries that discharge slowly and store a
17lot of power. Within a year they were dead too. Then I went for the more regular
18and cheaper ones, again with a lot of capacity. And yes, these also gave up, that
19is: only in the phones that were hardly used. The batteries lasted longer in
20phones that were discharged by usage daily.
21
22When I went out for new batteries I was asked if I needed them for cordless
23phones and, surprise, was given special ones that actually stored less but were
24guaranteed to work for at least 6 years. The package explicitly mentioned use in
25cordless phones. So here performance doesn't come with the most high end ones,
26based on specifications that impress.
27
28This is also true for computers that are used to process \TEX\ documents. More
29cores amount to much accumulated processing power but for a single core \TEX\
30process, a few fast cores are more relevant than plenty slower ones that run in
31parallel. More memory helps but compared to other processes \TEX\ actually
32doesn't use that much memory. And disk speed matters but less so when the
33operating system caches files. What does play a role are cpu caches because \TEX\
34is very memory intense and processing is not concentrated in a few functions. But
35a large cache shared among many (busy) cores makes for a less impressive
36performance.
37
38So what matters really? In the next sections we will explore a few points of
39view. It's not some advertisement for a specific engine, but much more about
40putting it into perspective (as one can run into ridiculous arguments on the
41web). It is not only the hardware and software that matters but also how one uses
42it.
43
44\stopsection
45
46\startsection[title=The engine]
47
48There are various ways to compare engines and each has its own characteristics.
49The \PDFTEX\ engine is closest to the original. It directly produces the output
50which can give it an edge. It is eight bit and therefore uses small fonts and
51internally all that is related to fonts and characters is also small. This means
52that there is little overhead in typesetting a paragraph: hyphenation, ligature
53building and kerning are interwoven and perform well.
54
55The \XETEX\ engine supports wide fonts and \UNICODE\ and therefore can be seen as
5632 bit. I never looked into the code so I can't tell how far that goes but
57performance is definitely less than \PDFTEX. The rendering of text is delegated
58to a library (there were some changes in that along its development) which is
59less efficient than the built in \PDFTEX\ route. But it is also more powerful.
60
61The \LUATEX\ engine is mostly 32 bit and delegates non standard font handling to
62\LUA\ which comes with a performance penalty but also adds a lot of flexibility.
63Also, the fact that one can call out to \LUA\ in many places makes that one can
64not really blame the engine for performance hits. The fact that hyphenation,
65ligature building and kerning is split comes at a small price too. We have larger
66nodes so compared to \PDFTEX\ more memory is used and accessed. Some mechanisms
67are actually more efficient, like font expansion and protrusion.
68
69The \LUAMETATEX\ engine lacks a font loader (but it does have the traditional
70renderer on board) and it has no backend. So even more is delegated to \LUA,
71which in turn makes this the slowest of the lot. And, again more data travels
72with nodes. In some modes of operation much more calculations take place.
73However, because it has an enriched macro processor, additional primitives, and
74plenty deep down \quote {improvements} it can perform better than \LUATEX\ (and
75even \LUAJITTEX, the \LUATEX\ version with a faster but limited \LUA\ virtual
76machine). And as with \LUATEX, there are usage patterns that make it faster than
77\PDFTEX.
78
79So, in general the order of performance is \PDFTEX, \XETEX, \LUAJITTEX\ (kind of
80obsolete), \LUATEX, \LUAMETATEX. But then, how come that \CONTEXT\ users never
81complain about performance? The reasons is simple: performance is quite okay and
82as it is relative to what one does, a user will accept a drop in performance when
83more has to be done. When we moved on from \LUATEX\ to \LUAMETATEX\ there
84definitely was a drop in performance, simply because of the \LUA\ backend.
85Because upgrading happened in small (but continuous) steps, right from the start
86the new engine was good enough to be used in production which is why most users
87switched to \LMTX\ as soon as became clear that this is where the progress is
88made.
89
90There were no real complaints about the upto 15\percent\ initial performance drop
91which indicates that for most users it doesn't matter that much. As the engine
92evolved we could gain some back and now \LUAMETATEX\ ends up between \PDFTEX\ and
93\LUATEX\ and in many modern scenarios even comes out first. The fact that in the
94meantime we can be much faster than \LUATEX\ did get noticed (when asked).
95However, as development takes years updating a machine in the meantime puts
96discussions about performance in a different (causality) perspective anyway.
97
98\stopsection
99
100\startsection[title=The coding]
101
102Performance can increase when native engine features are used instead of complex
103macros that have to work around limitations. It can also decrease when new
104features are used that add complex functionality. And when an engine extends
105existing functionality that is likely to come at a price. So where \LUAMETATEX\
106provides a more rich programming environment, it also had a more complex par
107builder, page builder, insert, mark and adjust handling, plenty of extra
108character, rule and box features and all of that definitely adds some overhead.
109Quite often a gain in simplicity (nicer and more efficient macros) compensate the
110more complex features. That is because on the average the engine doesn't do that
111much (tens of thousands of the same) complex macro expansion and also doesn't
112demand that much complex low level typesetting. A gain here is often compensated
113by a loss there. This is one reason why during the years \LUAMETATEX\ could
114sustain a decent performance. Personally I don't accept a drop in performance
115easily which is why in practice most mechanism, even when extended, probably
116perform better but I'm not going to prove that observation.
117
118One important reason why \CONTEXT\ \LMTX\ with \LUAMETATEX\ is faster than its
119ancestors is that we got rid of some intermediate programming layers. Most users
120have never seen the auxiliary macros or implementation details but plenty were
121used in \MKII\ and \MKIV. Of course we kept them because often they are nicer
122than many lines of primitive code, but only a few (and less in the future) are
123used in the core. Examples are multi step macros (that pick up arguments) that
124became single step and complex if tests that became inline native tests. Because
125\CONTEXT\ always had a high level of abstraction consistency of the interface
126also makes that we don't need many helpers. When some features (like for instance
127box manipulation) got extended one could expect a performance hit due to more
128extensive optional keyword scanning in the engine but that was compensated by
129improved scanners. The same is true for scanning numbers and dimensions. So, more
130functionality doesn't always come at a price.
131
132To summarize this: although the engine went a bit more \quote {cisc} than \type
133{risc} the macro package went more \quote {risc}. It reminds me a bit of the end
134of the previous century when there was much talk of fourth generation languages,
135something on top of the normal languages. In the end it were scripting languages
136that became the fashion while traditional languages like \CCODE\ remained
137relatively stable and unchanged for implementing them (and more). A similar
138observation can be made for \CONTEXT\ itself. Whenever some new feature gets
139added to an existing mechanism I try to not cripple performance and thanks to the
140way \CONTEXT\ is set up it works out okay.
141
142Let's look at an example. In \MKII\ we can compare two \quote {strings} with the
143macro \type {doifelse}. Its definition is as follows:
144
145\starttyping
146\long\def\doifelse#1#2%
147  {\let\donottest\dontprocesstest
148   \edef\!!stringa{#1}%
149   \edef\!!stringb{#2}%
150   \let\donottest\doprocesstest
151   \ifx\!!stringa\!!stringb
152     \expandafter\firstoftwoarguments
153   \else
154     \expandafter\secondoftwoarguments
155   \fi}
156\stoptyping
157
158This macro takes two arguments that gets expanded inside two helpers that we
159then compare with a primitive \type {\ifx}. Depending on the outcome we
160expand one of the two following arguments but first we get rid of the interfering
161\type {\else} and \type {\fi}. The pushing and popping of \type {\donottest} takes
162care of protection of unwanted expansion in an \type {\edef}. Many functional macros
163are what we call protected: then expand in two steps depending on the embedded
164\type {\donottest} macro. Think of (simplified):
165
166\starttyping
167\def\realfoo{something is done here}
168\def\usedfoo{\donottest\realfoo}
169\stoptyping
170
171Normally \type {\donottest} is doing nothing so \type {\realfoo} gets expanded
172but there are cases where we (for instance) \type {\let} it be \type {\string}
173which then serializes the macro. This is something that happens when writing to
174the multi pass data file. It can also be used for overloading, for instance in
175the backend or when converting something. This protection against expansion has
176always been a \CONTEXT\ feature, which in turn made it pretty robust in multi
177pass scenarios, but it definitely came with performance penalty.
178
179When \PDFTEX\ got the \ETEX\ extensions we could use the \type {\protected}
180prefix to replace this trickery. That means that \MKII\ will use a different
181definition of \type {\doifelse} when that primitive is known:
182
183\starttyping
184\long\def\doifelse#1#2%
185  {\edef\!!stringa{#1}%
186   \edef\!!stringb{#2}%
187   \ifx\!!stringa\!!stringb
188     \expandafter\firstoftwoarguments
189   \else
190     \expandafter\secondoftwoarguments
191   \fi}
192\stoptyping
193
194This works okay because we now do this:
195
196\starttyping
197\protected\def\usedfoo{something is done here}
198\stoptyping
199
200The \type {\doifelse} helper itself is not protected in \MKII\ (non \ETEX\ mode)
201It would be a performance hit. I won't bore the reader with the tricks needed to
202do the opposite, that is: expand a protected macro. It is seldom needed anyway.
203
204The \MKIV\ definition used with \LUATEX\ is not much different, only the \type
205{\long} prefix is missing. That one is needed when one wants \type {#1} and|/|or
206\type {#2} to be tolerant with respect to embedded \type {\par} equivalents. In
207\LUAMETATEX\ we can disable that check and in \CONTEXT\ all macros are thereby
208\type {\long}. Users won't notice because in \CONTEXT\ most macros were always
209defined the long way; we also suppress \type {\outer} errors.
210
211\starttyping
212\protected\def\doifelse#1#2%
213  {\edef\m_syst_string_one{#1}%
214   \edef\m_syst_string_two{#2}%
215   \ifx\m_syst_string_one\m_syst_string_two
216     \expandafter\firstoftwoarguments
217   \else
218     \expandafter\secondoftwoarguments
219   \fi}
220\stoptyping
221
222Implementation wise a macro, once scanned and stored, carries the long property
223in its command code so that has overhead. However because \LUATEX\ is compatible
224we cannot make all normal macros long by default when \type {\suppresslongerror}
225is used. Therefore checking for an argument running into a \type {\par} is still
226checked but the message is suppressed based on the setting of the mentioned
227parameter. Performance wise, not using \type {\long} comes a the cost of checking
228a parameter which means an additional memory access and comparison. Unless we
229otherwise gain something in the engine it comes at a cost. In \LUAMETATEX\ the
230\type {\long} and \type {\outer} prefixes are ignored. Even better, protected
231macros are also implemented a bit more efficiently.
232
233In the end the definition of \type {\doifelse} in \LMTX\ looks a bit different:
234
235\starttyping
236\permanent\protected\def\doifelse#1#2%
237  {\iftok{#1}{#2}%
238     \expandafter\firstoftwoarguments
239   \else
240     \expandafter\secondoftwoarguments
241   \fi}
242\stoptyping
243
244The \typ {\permanent} prefix flags this macro as such. Depending on the value of
245\typ {\overloadmode} a redefinition is permitted, comes with a warning or
246results in a fatal error. Of course this comes at a price when we define macros
247or values of quantities but this is rather well compensated by all kind of
248improvements in handling macros: defining, expansion, saving and restoring, etc.
249
250More interesting is the use of \type {\iftok} here. It saves us defining two
251helper macros. Of course the content still needs to be expanded before comparison
252but we no longer have various macro management overhead. In scenarios where we
253don't need to jump over the \type {\else} or \type {\fi} we can use this test in
254place which saves passing two arguments and grabbing one argument later on.
255Actually, grabbing is also different, compare:
256
257\starttyping
258          \def\firstoftwoarguments #1#2{#1} % MkII and MkIV
259\permanent\def\firstoftwoarguments #1#-{#1} % MkXL aka LMTX
260
261          \def\secondoftwoarguments#1#2{#1} % MkII and MkIV
262\permanent\def\secondoftwoarguments#-#1{#1} % MkXL aka LMTX
263\stoptyping
264
265In the case of \LUAMETATEX\ the \type {#-} makes that we don't even bother to
266store the argument as it is ignored. Where \type {#0} does the same it also
267increments the argument counter which is why here even the second arguments has
268number ~1. Now, if this more efficient? Sure, but how often does it really
269happen? The engine still needs to scan (which comes at a cost) but we save on
270temporary token list storage. Because \TEX\ is so fast already, measuring only
271shows differences when one has many (and here a real lot) iterations. However,
272all these small bits add up which is what we've seen in 2022 in \CONTEXT: it is
273the reason why we are now faster than \MKIV\ with \LUATEX, even with more
274functionality in the engine.
275
276I can probably write hundreds of pages in explaining what was added, changed,
277made more flexible and what side effects it had|/|has on performance but I bet no
278one is really interested in that. In fact, the previous exploration is just a
279side effect of a question that triggered it, so maybe future questions will
280trigger more explanations. It anyhow demonstrates what I meant when I said that
281\LUAMETATEX\ is meant to be leaner and meaner. Of course the code base and binary
282is smaller but that also gets compensated by more functionality. It also means
283that we can make the \CONTEXT\ code base nicer because for me a good looking
284source (which of course is subjective) is pretty important.
285
286\stopsection
287
288\startsection[title=Compatibility]
289
290There are non \CONTEXT\ users who seem to love to stress that successive versions
291of \CONTEXT\ are incompatible. Other claims are that it is developed in a
292commercial setting. While it is true that there are changes and it is also true
293that \CONTEXT\ is used in commercial settings, it is not that different from
294other open source projects. The majority of the code is written without
295compensation and it is offered without advertisements or request for support. It
296is true that when we can render better, it will be done. But the user interfaces
297only change when there is a reason and there are few cases where some
298functionality became obsolete, think of input and font encodings. Most such
299changes directly relate to the engine: in \PDFTEX\ and \MKII\ we emulate \UTF-8\
300wile in \LUATEX\ is comes natively. In \PDFTEX\ eight bit (\TYPEONE) fonts are
301used while \LUATEX\ adds support for \OPENTYPE. Other macro packages support that
302by additional packages while \CONTEXT\ has it integrated. That is why the system
303evolves over time.
304
305Just a users adapt to (yearly) operating system interfaces, mobile phones, all
306kinds of hardware, cars, clothing, media and so on, the \CONTEXT\ users have no
307problem adapting to an evolving \TEX\ ecosystem. I guess claims about changes
308(being a disadvantage) can only point to a lack of development elsewhere. The
309main reason for mentioning this is that when \CONTEXT\ users move on to newer
310engines, the older ones are seldom used. So, few users compare a \LMTX\ run with
311one using \PDFTEX\ or \LUATEX. They naturally expect \LUAMETATEX\ to perform well
312and maybe even to perform better over time. They just don't complain. And unless
313one hacks (overloads) system macros compatibility is not really an issue. What
314can be an issue is that updates and adaptations to a newer engine come with bugs
315but those are solved.
316
317So, the fact that we compare incompatible engines with likely different low level
318macro implementations of otherwise stable features of a macro package makes
319comparison hard. For instance, maybe there are speedups possible in frozen \MKII,
320although it is unlikely, which makes that it might even perform better than
321reported. In a similar fashion, the fact that \OPENTYPE\ is more demanding for
322sure makes that \LUATEX\ rendering is slower than \PDFTEX. It anyhow makes a
323discussion about performance within and between macro packages even more
324ridiculous. Just don't buy those claims and|/|or ask on the \CONTEXT\ mailing
325list for clarification.
326
327\stopsection
328
329\startsection[title=The job]
330
331So, say that we now have an efficient and powerful engine and a matching macro
332package. Does that make all jobs faster? For sure, the ones that I use as
333benchmark run much smoother. The 360 page \LUAMETATEX\ manual runs in less than
3348.4 seconds on a Dell Precision laptop with (mobile) Intel(R) Xeon(R) CPU
335E3-1505M v6 @ 3.00GHz, 2TB fast Samsung pro SSD, and 48 GB of memory, running
336Windows 10. The \METAFUN\ manual with many more pages and thousands of \METAPOST\
337graphics needs a bit more than 12 seconds. So you don't hear me complain. This
338chapter takes 7.5 seconds plus 0.5 is for the runner, not enough time to get
339coffee.
340
341Nowadays I tend to measure performance in terms of pages per second, because in
342the end that is what users experience. For me more important are the gains for my
343colleague who processes documents of 400 pages from hundreds of small \XML\ files
344with multiple graphics per page. Given different output variants a lot of
345processing takes place, so there a gain from 20 pages per second to 25 pages per
346second is welcome. Anyway, here are a few measurements of a {\em simple} test suite
347per January 7, 2023. We use this as test text:
348
349\starttyping
350\def\Knuth{%%
351Thus, I came to the conclusion that the designer of a new system
352must not only be the implementer and first large||scale user; the
353designer should also write the first user manual.
354\par
355The separation of any of these four components would have hurt
356\TeX\ significantly. If I had not participated fully in all these
357activities, literally hundreds of improvements would never have
358been made, because I would never have thought of them or perceived
359why they were important.
360\par
361But a system cannot be successful if it is too strongly influenced
362by a single person. Once the initial design is complete and fairly
363robust, the real test begins as people with many different
364viewpoints undertake their own experiments.
365}
366\stoptyping
367
368Now keep in mind that these are simple examples. On more complex documents the
369\LUAMETATEX\ engine with \LMTX\ is relatively faster: think \XML, plenty
370\METAPOST, complex tables, advanced math, dozens of fonts in combination with the
371new compact font mode.
372
373The tests themselves are simple: we switch fonts (because fonts bring overhead),
374we add some color (because we use different methods), we process some graphics
375(to show what embedding \METAPOST\ brings), we do some tables (because that can
376be stressful). Each sample is run 50, 500 or 1000 times, and each set is run a
377couple of times so that we compensate for caching and fluctuating system load.
378The tests are more about signaling a trend than about absolute numbers. For
379what it's worth, I used a \LUA\ script to run the samples.
380
381When you run an experiment that measures performance, keep in mind that
382performance not only depends on the engine, but also on for instance logging.
383When I run the \CONTEXT\ test suite it takes 1250 seconds if the console takes
384the full screen on a 2560 by 1600 display and 30 seconds more on a 3840 by 2160
385display and it even depends on how large the font is set. On the 1920 by 1200
386monitor I get to 1230. Of course these times change when we add more to the test
387suite so it's always a momentary measurement.
388
389Similar differences can be observed when running in an editor. A good test is
390making a \CONTEXT\ format: 2.2 seconds goes down to below 1.8 when the output is
391piped to a file. On a decent 2023 desktop those times are probably half but I
392don't have one at hand.
393
394\startsubsubject[title={sample 1, number of runs: 2}]
395
396\starttyping
397\starttext
398    \dorecurse {%s} {
399        \Knuth
400        \par
401    }
402\stoptext
403\stoptyping
404
405\starttabulate[||r|r|r|]
406\HL
407\BC engine \BC 50 \BC 500 \BC 1000 \NC \NR
408\HL
409\BC pdftex     \NC 0.63 \NC 0.83 \NC 1.07 \NC \NR
410\BC luatex     \NC 0.95 \NC 1.86 \NC 2.94 \NC \NR
411\BC luametatex \NC 0.61 \NC 1.49 \NC 2.48 \NC \NR
412\HL
413\stoptabulate
414
415\stopsubsubject
416
417\startsubsubject[title={sample 2, number of runs: 2}]
418
419\starttyping
420\starttext
421    \dorecurse {%s} {
422        \tf \Knuth \bf \Knuth
423        \it \Knuth \bs \Knuth
424        \par
425    }
426\stoptext
427\stoptyping
428
429\starttabulate[||r|r|r|]
430\HL
431\BC engine \BC 50 \BC 500 \BC 1000 \NC \NR
432\HL
433\BC pdftex     \NC 0.70 \NC 1.73 \NC 2.80 \NC \NR
434\BC luatex     \NC 1.37 \NC 5.37 \NC 9.92 \NC \NR
435\BC luametatex \NC 1.04 \NC 5.06 \NC 9.73 \NC \NR
436\HL
437\stoptabulate
438
439\stopsubsubject
440
441\startsubsubject[title={sample 3, number of runs: 2}]
442
443\starttyping
444\starttext
445    \dorecurse {%s} {
446        \tf \Knuth \it knuth \bf \Knuth \bs knuth
447        \it \Knuth \tf knuth \bs \Knuth \bf knuth
448        \par
449    }
450\stoptext
451\stoptyping
452
453\starttabulate[||r|r|r|]
454\HL
455\BC engine \BC 50 \BC 500 \BC 1000 \NC \NR
456\HL
457\BC pdftex     \NC 0.71 \NC 1.81 \NC 2.98 \NC \NR
458\BC luatex     \NC 1.41 \NC 5.84 \NC 10.77 \NC \NR
459\BC luametatex \NC 1.05 \NC 5.71 \NC 10.60 \NC \NR
460\HL
461\stoptabulate
462
463\stopsubsubject
464
465\startsubsubject[title={sample 4, number of runs: 2}]
466
467\starttyping
468\setupcolors[state=start]
469\starttext
470    \dorecurse {%s} {
471        {\red \tf \Knuth \green \it knuth}
472        {\red \bf \Knuth \green \bs knuth}
473        {\red \it \Knuth \green \tf knuth}
474        {\red \bs \Knuth \green \bf knuth}
475        \par
476    }
477\stoptext
478\stoptyping
479
480\starttabulate[||r|r|r|]
481\HL
482\BC engine \BC 50 \BC 500 \BC 1000 \NC \NR
483\HL
484\BC pdftex     \NC 0.73 \NC 1.91 \NC 3.64 \NC \NR
485\BC luatex     \NC 1.39 \NC 5.82 \NC 12.58 \NC \NR
486\BC luametatex \NC 1.07 \NC 5.57 \NC 11.85 \NC \NR
487\HL
488\stoptabulate
489
490\stopsubsubject
491
492\startsubsubject[title={sample 5, number of runs: 2}]
493
494\starttyping
495\starttext
496    \dorecurse {%s} {
497        \null \page
498    }
499\stoptext
500\stoptyping
501
502\starttabulate[||r|r|r|]
503\HL
504\BC engine \BC 50 \BC 500 \BC 1000 \NC \NR
505\HL
506\BC pdftex     \NC 0.62 \NC 1.12 \NC 1.68 \NC \NR
507\BC luatex     \NC 0.90 \NC 1.39 \NC 1.98 \NC \NR
508\BC luametatex \NC 0.58 \NC 0.99 \NC 1.46 \NC \NR
509\HL
510\stoptabulate
511
512\stopsubsubject
513
514\startsubsubject[title={sample 6, number of runs: 2}]
515
516\starttyping
517\starttext
518    \dorecurse {%s} {
519        %% nothing
520    }
521\stoptext
522\stoptyping
523
524\starttabulate[||r|r|r|]
525\HL
526\BC engine \BC 50 \BC 500 \BC 1000 \NC \NR
527\HL
528\BC pdftex     \NC 0.55 \NC 0.54 \NC 0.56 \NC \NR
529\BC luatex     \NC 0.79 \NC 0.81 \NC 0.82 \NC \NR
530\BC luametatex \NC 0.54 \NC 0.52 \NC 0.53 \NC \NR
531\HL
532\stoptabulate
533
534\stopsubsubject
535
536\startsubsubject[title={sample 7, number of runs: 2}]
537
538\starttyping
539\starttext
540    \dontleavehmode
541    \dorecurse {%s} {
542        \framed[width=1cm,height=1cm,offset=2mm]{x}
543    }
544\stoptext
545\stoptyping
546
547\starttabulate[||r|r|r|]
548\HL
549\BC engine \BC 50 \BC 500 \BC 1000 \NC \NR
550\HL
551\BC pdftex     \NC 0.58 \NC 0.65 \NC 0.71 \NC \NR
552\BC luatex     \NC 0.84 \NC 0.96 \NC 1.08 \NC \NR
553\BC luametatex \NC 0.54 \NC 0.62 \NC 0.72 \NC \NR
554\HL
555\stoptabulate
556
557\stopsubsubject
558
559\startsubsubject[title={sample 8, number of runs: 2}]
560
561\starttyping
562\starttext
563    \dontleavehmode
564    \dorecurse {%s} {
565        \framed
566          [width=1cm,height=1cm,offset=2mm,
567           foregroundstyle=bold,foregroundcolor=red,
568           background=color,backgroundcolor=green]
569          {x}
570    }
571\stoptext
572\stoptyping
573
574\starttabulate[||r|r|r|]
575\HL
576\BC engine \BC 50 \BC 500 \BC 1000 \NC \NR
577\HL
578\BC pdftex     \NC 0.59 \NC 0.70 \NC 0.83 \NC \NR
579\BC luatex     \NC 0.87 \NC 1.00 \NC 1.17 \NC \NR
580\BC luametatex \NC 0.55 \NC 0.66 \NC 0.78 \NC \NR
581\HL
582\stoptabulate
583
584\stopsubsubject
585
586\startsubsubject[title={sample 9, number of runs: 2}]
587
588\starttyping
589\starttext
590    \ifdefined\permanent\else\def\BC{\NC\bf}\fi
591    \dontleavehmode
592    \dorecurse {%s} {
593        \starttabulate[|||||]
594            \NC test \BC test \NC test \NC test \NC \NR
595            \NC test \BC test \NC test \NC test \NC \NR
596            \NC test \BC test \NC test \NC test \NC \NR
597            \NC test \BC test \NC test \NC test \NC \NR
598        \stoptabulate
599    }
600\stoptext
601\stoptyping
602
603\starttabulate[||r|r|r|]
604\HL
605\BC engine \BC 50 \BC 500 \BC 1000 \NC \NR
606\HL
607\BC pdftex     \NC 0.62 \NC 1.15 \NC 1.71 \NC \NR
608\BC luatex     \NC 0.94 \NC 1.84 \NC 2.86 \NC \NR
609\BC luametatex \NC 0.60 \NC 1.19 \NC 1.88 \NC \NR
610\HL
611\stoptabulate
612
613\stopsubsubject
614
615\startsubsubject[title={sample 10, number of runs: 2}]
616
617\starttyping
618\starttext
619    \dontleavehmode
620    \dorecurse {%s} {
621        \startMPcode
622            fill fullcircle scaled 1cm withcolor red ;
623            fill fullsquare scaled 1cm withcolor green ;
624        \stopMPcode
625        \space
626    }
627\stoptext
628\stoptyping
629
630\starttabulate[||r|r|r|]
631\HL
632\BC engine \BC 50 \BC 500 \BC 1000 \NC \NR
633\HL
634\BC pdftex     \NC 5.73 \NC 50.98 \NC 102.10 \NC \NR
635\BC luatex     \NC 0.93 \NC 1.07 \NC 1.30 \NC \NR
636\BC luametatex \NC 0.57 \NC 0.71 \NC 0.86 \NC \NR
637\HL
638\stoptabulate
639
640\stopsection
641
642\startsection[title=Final words]
643
644Whenever I run into (or get send) remarks of (especially non \CONTEXT) users
645suggesting that \LUATEX\ is much slower than \PDFTEX\ or that \LUAMETATEX\ seems
646much faster than \LUATEX, one really has to keep in mind that this is not always
647true. Among the questions to be asked are \quotation {What engine do you use?},
648\quotation {Which macro package do you use?}, \quotation {How well is your style
649set up?}, \quotation {How complex is the document?}, \quotation {Is your own
650additional code efficient?}, \quotation {Do you use engine and macro package
651features the right way?} and of course \quotation {What do you compare with?},
652\quotation {What do you expect and why?}, \quotation {Do you actually know what
653goes on deep down?}. An embarrassing one can be \quotation {Do you have an idea
654what is involved in fulfilling your request given that we use a flexible adaptive
655macro language?}. Much probably these questions not get answered properly.
656
657Another thing to make clear is that when someone claims for instance that
658\CONTEXT\ \LMTX\ is fast because of \LUAMETATEX, or that \LUAMETATEX\ is much
659faster than \LUATEX, a healthy suspicion should kick in: does that someone really
660knows what happens and matters? The previous numbers do show differences for
661simple cases but we're often not talking of differences that can be used as an
662excuse for insufficient coding. In the end it is all about the experience: does
663performance feel in tune with expectations. Which is not to say that I will make
664\CONTEXT\ and \LUAMETATEX\ faster because after all there are usage scenarios
665where one has to process tens of thousands of documents with a reasonable amount
666of time, on regular infrastructure, and of course with as little as possible
667energy consumption.
668
669If \PDFTEX\ suits your purpose, there is no need to move to \LUATEX. As with
670rechargeable batteries in cordless phones a higher capacity can make things
671worse. If \LUATEX\ fits the bill, don't dream about using \LUAMETATEX\ instead
672because it will half runtime because the adaptations needed in the macro package
673(like adding a backend) might actually slow it down. Moores law doesn't apply to
674\TEX\ engines and macro packages and you might get disappointed. Accept that the
675choice you made for a macro package can come with a price.
676
677Quite often it is rather easy to debunk complaints and claims which makes one
678wonder why claims about perceived or potential are made at all. But then, I'm
679accustomed to weird remarks and conclusions about \CONTEXT\ as a macro package,
680or for that matter \LUATEX\ (as it originates in the \CONTEXT\ community) even by
681people who should know better. Hopefully the above invites to being more careful.
682
683\stopsection
684
685\stopchapter
686
687\stopcomponent
688