如何使用 console.time 进行微基准测试,以测量编译器优化中的微小差异?

2024-02-27

该代码是对另一个 https://stackoverflow.com/a/39087644/287948...这是一个丑陋的代码,但问题是关于“如何进行基准测试”。

  1. The new console.time https://developer.mozilla.org/en-US/docs/Web/API/Console/time函数测量“实际执行时间”还是不太可靠?它真的对所有浏览器都可靠吗?还是可以稍微改变一下?
    PS:用起来比较好Date.now()(或者类似 Unix 终端time)、外部时间参考?

  2. 如何检查“编译器优化”是否忽略不执行任何操作的循环?

下面的基准旨在衡量运营成本== and ===这几乎是一样的。问题是每个浏览器(Firefox 和 Chrome)会导致不同的平均时间......所以,

  1. 当优化相反时,使用“所有浏览器的平均时间”有意义吗?还有另一种方法来估计执行时间吗?

在不同的浏览器中自行测试,或者也使用 NodeJs...并记住它is not通常的表现(“哪个更快?”),但是现实的衡量标准,一种检查编译器正在做什么(平均)来实现 ECMA 262 规定的方法。

var testString = "444442";
var testNumber = 444442;
var testString2 = "444443";
var testObject = {};
var testObject2 = {x:1};

const MAX = 1000000;
var name;
var result;

name='===';
result = 0;
console.time('Operation '+name);
for(var i = 0; i < MAX; i++){
    result += Number(
       (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
       &&      (testString2 === testString || testNumber === testNumber) && (testObject2 === testObject || testString === testString) && (result === testNumber || testObject === testObject)
      )
      testNumber++
}
console.timeEnd('Operation '+name);

var result0 = result;

name='=='
result = 0;
console.time('Operation '+name);
var result = null;
for(var i = 0; i < MAX; i++){
  result += Number(
    (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
    &&      (testString2 == testString || testNumber == testNumber) && (testObject2 == testObject || testString == testString) && (result == testNumber || testObject == testObject)
  )
}
console.timeEnd('Operation '+name);

if (result0 != result)
console.log("OOPS BUG, result0 differing result: ", result0, result)

name='NoOp'
result = 0;
console.time('Operation '+name);
for(var i = 0; i < MAX; i++){
    result =  true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true &&
    true && true && true
}
console.timeEnd('Operation '+name);

结果示例(消零毫秒)

在火狐浏览器上:

操作===:80毫秒 操作==:200毫秒 空操作:8 毫秒

在 Chrome 上:

操作 ===:21 毫秒 操作==:27毫秒 空操作:22 毫秒

在 NodeJS 上:

操作 ===:108 毫秒 操作==:152毫秒 空操作:9 毫秒

结论:===在所有编译器中都快一点。


The problem:运行其他引用的代码,这个答案 https://stackoverflow.com/a/39087644/287948(“瑞克测试”),

在火狐浏览器上:

操作===:1089u 操作==:280u 空操作:281 u

在 Chrome 上:

操作===:352u 操作==:349 u 空操作:349 u

在 NodeJS 上:

操作===:201u 操作==:387 u 空操作:195 u

结论:== (not ===) 在浏览器中速度更快,但在 Node 中则相反。


最终结论:即使使用更多循环等,基准测试结果也不会收敛。似乎 Rick 的测试经过了优化(随着编译器的变化而变化),而上面的情况则没有。

最终结论:即使使用更多循环等,基准测试结果也不会收敛。似乎 Rick 的测试受到(依赖于编译器的)优化,而上述测试(在本页中)则不然。

PS:当然,理想情况下(根据规范)运营商== and ===比较相同的数据类型时具有相同的时间,因此很难测量差异...但这就是问题,我想检查这个小小的差异console.time.


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 console.time 进行微基准测试,以测量编译器优化中的微小差异? 的相关文章

随机推荐