我一直在尝试对 Lua 代码进行一些微基准测试,但遇到了一个非常烦人的问题:我似乎无法获得一致的结果。
示例:这是一个非常简单的 Lua 程序,它应该对一个简单的 Fibonacci 函数进行计时:
function pfibs(n)
if n ~= math.floor(n) then return 0
elseif n < 0 then return pfibs(n + 2) - pfibs(n + 1)
elseif n < 2 then return n
else return pfibs(n - 1) + pfibs(n - 2)
end
end
t = os.clock()
pfibs(30)
t = os.clock() - t
print("time: "..t)
当我尝试连续运行几次时,会发生以下情况:
$ lua fib.lua
time: 1.265
$ lua fib.lua
time: 1.281
$ lua fib.lua
time: 1.343
$ lua fib.lua
time: 1.437
$ lua fib.lua
time: 1.562
$ lua fib.lua
time: 1.578
$ lua fib.lua
time: 1.64
$ lua fib.lua
time: 1.703
$ lua fib.lua
time: 1.75
$ lua fib.lua
time: 1.797
$ lua fib.lua
time: 1.796
$ lua fib.lua
time: 1.812
$ lua fib.lua
time: 1.89
(这只是一个例子,为简洁起见,但代表了我所看到的那种减速曲线)
从 1.1 秒左右开始的时间最终远远超过 2 秒。我一直在做的就是坐在这里反复按上进。time
如果我将测试包装在调用中而不是使用 Lua 时钟,或者如果我让它循环几次以多花几秒钟,也会发生同样的事情;它似乎按比例减慢。如果我离开它一段时间,有时时间会倒退。有时不会(可能是因为我不知道要离开多久)。
这是在 Windows+MSYS 上。在 Ubuntu(同一台机器)上尝试这个会导致不同的模式,但仍然非常不一致和不可用的结果(例如,测试需要 2 秒,然后是 3.5 秒,然后是 4 秒,然后是 2.5 秒......)。任务管理器/顶部表明在任何一种情况下都不会在后台占用 CPU。CPU 速度切换被禁用。
我究竟做错了什么?我的机器很旧,但它不会那么坏(如果是机器的故障,我肯定会注意到它无法使用,并且每个程序每秒都变得慢得多......)。
我实际上正在尝试做的事情:
我想做的是了解解释器的实现,从 vanilla Lua 开始并对其进行调整以查看更改对解释器性能的影响。正如你所看到的,我还没有通过“建立控制”,所以我实际上还没有做过任何事情——基准方差与上面一样高,我所做的任何更改都将完全丢失在噪音。我选择 Lua 是因为虽然它是一个真实世界的程序,但它也很小且易于阅读和修改。如果有更好的基础解释器可以做到这一点,或者有一个既定的最佳方式来衡量解释器的性能,请随时在答案中添加建议。
编辑:添加C
标签是因为在使用传统 C 计时实用程序的 C 程序中也会发生同样的事情,例如:
#include <time.h>
#include <stdio.h>
int fib(int n) {
return n > 2 ? fib(n - 1) + fib(n - 2) : n;
}
int main(void) {
clock_t t1, t2; const int ITNS = 30;
for (int i = 0; i < ITNS; i ++) {
t1 = clock();
fib(38);
t2 = clock();
printf("time: %d\n", (int)((t2 - t1) / (CLOCKS_PER_SEC / 1000)));
}
return 0;
}
...打印以下内容:
time: 687
time: 688
time: 687
time: 688
time: 671
time: 688
time: 687
time: 688
time: 672
time: 687
time: 688
time: 687
time: 672
time: 688
time: 687
time: 688
time: 672
time: 796
time: 766
time: 719
time: 969
time: 1000
time: 1015
time: 1000
time: 1016
time: 1000
time: 1000
time: 1015
time: 1000
time: 1000
这表明效果不限于单独运行。我想这意味着机器或操作系统存在问题。