在一个最近的问题,Yiannis Lazarides 询问了有关基准测试循环的问题。奇怪的是,他的结果比我的快了大约 800 倍。我无法接受我的电脑如此过时(因为我几个月前才买的)。主要区别似乎是我在 Linux 上编译文件,而他在 Windows 上编译。所以我在 Windows 分区上安装了 MikTeX 来亲自尝试,结果让我非常惊讶。
这是 Yiannis 代码的稍微简化版本(可运行pdflatex
)
\documentclass{article}
\usepackage{ifthen}
\def\startTimer{\pdfresettimer}
\def\stopTimer{\the\pdfelapsedtime\,scaled seconds}
\begin{document}
\startTimer
\newcounter{acount}
\whiledo{\value{acount}<888}{%
\stepcounter{acount}%
\theacount, }
\stopTimer
\end{document}
在 Linux(Ubuntu 10.10 64 位、TeX Live 2010(32 位和 64 位))上,计时器报告约 1700 秒。在 Windows(7、64 位、MikTeX 2.9(32 位?))上,结果是 2 秒。
我非常肯定 850 的倍数并非完全归因于操作系统(两个测试都在同一台机器上运行)。此外,在两个操作系统上编译“真实”文档似乎花费的时间大致相同。差异来自何处?
答案1
在这个(非常小的)运行时间内,结果很可能由 pdftex 使用的 Windows 和 Linux 系统函数调用之间的实现差异决定。Pdftex 在两个平台上运行的代码并不相同,而 Windows 上使用的函数实现(ftime)因在小间隔内不可靠而臭名昭著。
除此之外,还要记住,\pdfelapsedtime
测量的是挂钟时间差,而不是实际的计算机使用情况pdftex
。计算机上可能(并且很可能)同时进行许多其他操作。操作系统本身的中间任务切换可能会对结果产生相当大的影响。
正如我在另一个帖子中已经写过的:你不应该相信任何小于一秒(65536 秒)的基准测试值。另外,确保在尽可能少做其他事情的机器上多次运行代码。
答案2
回复评论:这是一个更加现实的测试。
TeX 文件:
\documentclass{article}
\usepackage{ifthen}
\newwrite\BenchmarkStream
\def\startTimer{%
\pdfresettimer
\immediate\openout\BenchmarkStream=\jobname.dat
}
\def\stopTimer{%
\immediate\write\BenchmarkStream{\number\pdfelapsedtime}%
\immediate\closeout\BenchmarkStream
}
\begin{document}
\startTimer
\newcounter{acount}
\whiledo{\value{acount}<28888}{%
\stepcounter{acount}%
\theacount, }
\stopTimer
\end{document}
Python 脚本:
#!/usr/bin/env python2.6
from __future__ import unicode_literals, division, print_function
import subprocess
import numpy
def run():
args = ["pdflatex", "--interaction=batchmode", "test.tex"]
subprocess.check_call(args)
with open("test.dat", "rt") as stream:
return int(stream.read()) / 0x10000
def main():
# warm up
for i in xrange(10):
run()
count = 50
result = numpy.empty(count)
for i in xrange(count):
print("Iteration", i)
result[i] = run()
imin = result.argmin()
imax = result.argmax()
print("Count:", count)
print("Minimum:", result[imin], "at", imin)
print("Maximum:", result[imax], "at", imax)
print("Mean:", result.mean())
print("Median:", numpy.median(result))
print("Standard deviation:", result.std())
if __name__ == "__main__":
main()
我的Linux系统上的结果是:
Minimum: 1.05038452148 at 0
Maximum: 1.20942687988 at 30
Mean: 1.07401489258
Median: 1.05834197998
Standard deviation: 0.039375040446