如何提高 Javascript 的基准测试准确性?

问题描述 投票:0回答:1

我正在寻找一种方法来对 Javascript 函数的性能进行基准测试,以便我可以更有效地优化它。生成的数字(平均刻度持续时间)在运行/测试中应该是准确的,理想情况下运行之间的偏差不超过 2%,但我经常编写的代码偏差超过 30%。

这是我的代码的简化版本:

let j = 0;
while (true) {
   // Collect garbage from previous run
   for (let i = 0; i < 10; i++) {
      global.gc();
   }
   
   // Reset the board state
   Board.reset();

   // Seed the random number generator
   SRandom.seed(40404040404);
   
   Board.setup();
   SERVER.setup();

   // Warm up the JIT
   for (let i = 0; i < 50; i++) {
      SERVER.tick();
   }
   
   const numTicks = 5000;
   
   const startTime = performance.now();

   for (let i = 0; i < numTicks; i++) {
      SERVER.tick();
   }

   const timeElapsed = performance.now() - startTime;
   const averageTickTimeMS = timeElapsed / numTicks;
   console.log("(#" + (j + 1) + ") Average tick MS: " + averageTickTimeMS);
   j++;
}

代码在 Node JS 上运行,当我运行它时,我会关闭尽可能多的其他程序,通常只留下 chrome、VSCode(我用来运行代码的)和终端打开。

这确实对游戏进行了基准测试,因此涉及大量随机数生成,但在基准测试之前,我使用种子随机数生成器(

Math.random = () => SRandom.next()
)覆盖内置 Math.random 并在每次运行时重新种子。

下面是我运行基准测试时的输出:

(#1) Average tick MS: 4.773744156002999
(#2) Average tick MS: 3.103633259952068
(#3) Average tick MS: 3.431657537043095
(#4) Average tick MS: 3.3931038970351217
(#5) Average tick MS: 3.557662303030491
(#6) Average tick MS: 3.6041946840286254
(#7) Average tick MS: 3.570515029013157
(#8) Average tick MS: 3.8610670589804648
(#9) Average tick MS: 3.758602159976959
(#10) Average tick MS: 3.6722980710268023

我不确定为什么第一次运行需要这么长时间,但排除该运行,运行 2 和运行 8 之间存在 24% 的偏差。

如何使基准测试更加准确?或者这是 Javascript 的基本限制。

javascript node.js benchmarking
1个回答
0
投票

如果 JS 代码不依赖于 Network/DOM,我建议获取最小值。否则你无法控制偏差,但你可以再次获得最小值、最大值和平均值。

另请注意,制定 5 毫秒的基准测试并不能提供太多信息,请尝试循环您的逻辑,以便您的 1 次基准测试运行至少为 100 毫秒。然后将基准时间除以循环数。

在我的基准测试中,我尝试通过自动循环估计达到最小值:

// @benchmark Array.join()
let count = 100000;
const arr = [];
while(count--) arr.push('0');
arr.join('');

// @benchmark String concat
{
let count = 100000;
let str = ''
while(count--) str +='0';
str;
}

/*@end*/eval(atob('e2xldCBlPWRvY3VtZW50LmJvZHkucXVlcnlTZWxlY3Rvcigic2NyaXB0Iik7aWYoIWUubWF0Y2hlcygiW2JlbmNobWFya10iKSl7bGV0IHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7dC5zcmM9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9naC9zaWxlbnRtYW50cmEvYmVuY2htYXJrL2xvYWRlci5qcyIsdC5kZWZlcj0hMCxkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHQpfX0='));

© www.soinside.com 2019 - 2024. All rights reserved.