Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

In pdfTeX, the \pdfelapsedtime primitive gives access to the time since this pdfTeX run was started, in "scaled seconds" (1/65536 seconds). This is useful to benchmark code: repeat it many times, and test the time it takes.

\newcount\benchmarkcount
\long\def\tenfold#1{#1#1#1#1#1#1#1#1#1#1}
\long\edef\thousandfold{\tenfold{\tenfold{\tenfold{#1}}}}
\long\def\benchmark#1{%
  \benchmarkcount\pdfelapsedtime
  \thousandfold{#1}%
  \typeout{\the\dimexpr\pdfelapsedtime sp-\benchmarkcount sp miliseconds}%
}

Is it possible to have access to the time in a similar way in XeTeX and/or LuaTeX?

share|improve this question
4  
XeTeX doesn't have the primitive and I don't think it's possible with it. –  egreg Oct 23 '11 at 23:01
    
Are you sure, your original code gives you milliseconds and not seconds? –  Andy Nov 28 '11 at 16:45
    
@Andy: I almost replied that you were right, but in fact, since I'm performing the code 1000 times (three uses of \tenfold), the total time in seconds is the time in milliseconds taken by one copy of the code. [Then, there is a typo, I should've written "millisecond".] –  Bruno Le Floch Dec 7 '11 at 9:12
add comment

1 Answer

up vote 15 down vote accepted

After some help from here, the following code seems to be pretty close to the original primitive. We look at the pdflatex release notes (2005-08-01) first

  • \pdfelapsedtime is a read-only integer that (initially) returns the amount of time passed since the start of this run. This amount is given in `scaled seconds': the value 65536 counts as one second. If more time has passed than 32767 seconds, (2^31)-1 will be returned.
  • \pdfresettimer updates the internal timer, such that subsequent calls to \pdfelapsedtime will restart from 0.

Now, the try to reimplement in user space:

\directlua{pdfelapsedtimer_basetime=0}

os.clock() counts from the start of lua, so it pdfelapsedtimer_basetime is set to zero. No need to read the initial os.clock() value, it is supposed to be 0 anyway. From lua.org:

The os.clock function returns the number of seconds of CPU time for the program. Its typical use is to benchmark a piece of code

If the user want to reset it, the pdflatex primitive is \pdfresettimer. In that case, we read out os.clock() and store it in pdfelapsedtimer_basetime to subtract the offset later.

\protected\def\pdfresettimer{\directlua{pdfelapsedtimer_basetime = os.clock()}}

Finally, the \pdfelapsedtime macro subtracts the offset to get seconds, multiplies by 65536 to get scaled seconds, adds 0.5 to allow the function math.floor proper rounding and returns an integer. We need an integer and not characters in the token stream, therefore, \numexpr is utilized.

\protected\def\pdfelapsedtime{\numexpr\directlua{tex.print(math.floor((os.clock()-pdfelapsedtimer_basetime)*65536+0.5))}\relax}

The following MWE is an implementation for the original question:

\documentclass{article}

\newcount\benchmarkcount
\long\def\tenfold#1{#1#1#1#1#1#1#1#1#1#1}
\long\edef\thousandfold#1{\tenfold{\tenfold{\tenfold{#1}}}}
\long\def\benchmark#1{%
  \benchmarkcount\pdfelapsedtime
  \thousandfold{#1}%
  \typeout{\the\dimexpr\pdfelapsedtime sp-\benchmarkcount  sp}%
}

\usepackage{lipsum}

\directlua{pdfelapsedtimer_basetime=0}
\protected\def\pdfresettimer{\directlua{pdfelapsedtimer_basetime = os.clock()}}
\protected\def\pdfelapsedtime{\numexpr\directlua{tex.print(math.floor((os.clock()-pdfelapsedtimer_basetime)*65536+0.5))}\relax}

\begin{document}
\benchmark{\lipsum}
\end{document}
share|improve this answer
    
Great! Since I want to put that into a package, I guess I shouldn't call the variable x, though. Is there a good method for name scoping? –  Bruno Le Floch Oct 24 '11 at 9:43
    
If you could code these macros to behave like the original primitives, then they would be good candidates for the pdftexcmds package which defines some of the missing pdftex primitives for LuaTeX. –  Martin Scharrer Oct 24 '11 at 11:13
    
@BrunoLeFloch: Use a lua table table, e.g. elapsedtime = {} elapsedtime.start = os.clock(), this is the lua name scoping way. –  Khaled Hosny Oct 24 '11 at 16:11
    
@BrunoLeFloch: I would try to do Martins suggestion, if someone is not already doing that. Otherwise I take it as an exercise :) –  Andy Oct 30 '11 at 20:26
2  
@MartinScharrer: Heiko Oberdiek edited and added the macros in the next version of pdftexcmds. –  Andy Nov 30 '11 at 6:02
show 2 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.