为什么这个循环在 Windows 下速度这么快?

为什么这个循环在 Windows 下速度这么快?

在一个最近的问题,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

相关内容