此代码是this other one的改编...这是一个丑陋的代码,但问题在于“如何进行基准测试”。
新的console.time
函数可测量“实际执行时间”,还是不太可靠? PS:最好使用Date.now()
(或类似Unix终端time
之类的外部时间参考)?
PS:更好吗?
如何将“编译器优化”视为忽略无用的循环?
以下基准旨在衡量==
和===
几乎相同的运营成本。问题在于每个浏览器(Firefox和Chorme)导致的平均时间不同...因此,
在不同的浏览器中或通过NodeJ自己进行测试...请记住,它不是通常的性能(“更快吗?”),而是现实,这是一种检查编译器正在平均执行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);
采样结果(切零毫秒)
在Firefox上:
操作===:80毫秒 操作==:200毫秒 NoOp操作:8毫秒
在Chrome上:
操作===:21毫秒 操作==:27毫秒 NoOp操作:22毫秒
在NodeJS上:
操作===:108毫秒 操作==:152毫秒 NoOp操作:9毫秒
结论:===
在所有编译器中都快一点。
问题:运行this answer(“ Rick测试”)的其他引用代码,
在Firefox上:
操作===:1089 u 操作==:280 u NoOp操作:281 u
在Chrome上:
操作===:352 u 操作==:349 u NoOp操作:349 u
在NodeJS上:
操作===:201 u 操作==:387 u NoOp操作:195 u
结论:==
(不是===
)在浏览器中速度更快,但在Node中则相反。
最终结论:即使使用更多循环等,基准结果也无法收敛。似乎Rick的测试经过了优化(在编译器上进行了更改),而上面的则没有。
最终结论:即使使用更多循环等,基准结果也不会收敛。似乎Rick的测试受到(依赖于编译器的)优化的影响,而上述测试(在此页中)则不受此限制。
PS:当然,理想情况下(根据规范),在比较相等的数据类型时,运算符==
和===
具有相同的时间,因此很难测量差异...但这是问题,我想用console.time
来检查一下这个小区别。