javascript - JS引擎处理数据,为什么不符合预期值
问题描述
我正在测试 JS 引擎处理不同级别数据的能力。但是这个结果让我很惊讶。
const step = [10,100,1000,10000,100000,1000000,10000000,100000000,1000000000];
let sum = 0;
step.forEach((item) => {
let n = item.toString().split('').length -1;
console.time(`10^${n}`);
while (item){
++sum;
--item;
}
console.timeEnd(`10^${n}`);
})
10^1 比 10^3 慢,或 10^5 比 10^6 慢,或两者兼而有之。
测试的runtime包括:chrome71,node 10.13.0,firefox64(还不错)
我不知道这是否是 V8 的行为。
我遵循了CertainPerformance的建议使用performance.now()
// nodeJs
//const { performance } = require('perf_hooks');
const step = [10,100,1000,10000,100000,1000000,10000000,100000000,1000000000];
let sum = 0;
step.forEach((item) => {
let n = item.toString().split('').length -1;
let t0 = performance.now();
while (item){
++sum;
--item;
}
let t1 = performance.now();
console.log(`10^${n}:`,t1-t0);
})
它会出现多次。
解决方案
您应该多次运行代码,因为代码第一次运行时,它永远不会优化,并且在您运行此代码时,JS 引擎会开始优化部分代码/功能。当你再次按下“运行代码片段”时,从技术上讲,它是一个新代码,优化器需要重新开始。
你会发现它在第一次运行后更加一致:
而且我不会过多地阅读 <0.1ms 范围内的波动以及由此产生的第一项之间的顺序差异。
const step = [10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000];
let sum = 0;
const test = (item) => {
let n = item.toString().split('').length - 1;
console.time(`10^${n}`);
while (item) {
++sum;
--item;
}
console.timeEnd(`10^${n}`);
};
const runTest = (times) => {
if (times > 0) {
sum = 0;
step.forEach(test);
console.log("----");
setTimeout(runTest, 10, times - 1);
}
}
runTest(10);
.as-console-wrapper {
top: 0;
max-height: 100%!important
}
旁注:您会看到,如果您不重置sum = 0
,运行几次后,运行时会上升。这是因为sum
达到了一个不再可以表示为 anint
而是变成 a 的值double
。这不仅++sum
会稍微贵一点,而且由于迭代次数太多而加起来,而且它还否定了优化器对代码中类型的假设sum
,这导致代码的 deopt 和之后的 100-150迭代(未优化)在新假设下对代码的重新优化sum
是int
or double
,这也++sum
比它只是一个int
.
推荐阅读
- c# - 在非 UI 应用程序中,如何处理“调用线程无法访问此对象,因为不同的线程拥有它”
- amazon-cognito - 如何将 OpenID 身份验证从 Blazor WebAssembly 传递到 .NET Core WebApi 后端,两者都使用 Cognito 作为 OpenID 提供程序?
- node.js - 运行“create-react-app my-app”后尝试运行“npm start”时出现一堆错误
- c++ - 可变数据结构模板实例化
- node.js - 无法在本地使用 NodeJS 连接到 AWS DocumentDB
- python - 使用 Haar Cascade(或 LBP)或其他方法进行专业爆头检测
- python - 将总计和平均值分配给深度嵌套的列熊猫多索引
- html - 如何将 json 文件中的 FontAwesome 图标渲染到 React 应用程序中?
- sql - SQL Server 存储过程在微小更改后需要很长时间才能运行
- java - 我是错误地构建了 Java 10 还是其他原因?在 Pi4 上运行 MapTool(几乎!InteropFactoryN 有问题?)