我目前正在自己创建一个简短的 javascript 演示,只是为了检查功能性能。代码如下:
(function(){
'use strict';
var getFunctionExecuteTime = function(myFoo) {
if(typeof myFoo !== 'function'){
return -1;
}else{
var t1 = performance.now();
myFoo();
var t2 = performance.now();
return t2-t1;
}
};
var foo = function() {
console.log('running.');
};
function foo2(){
console.log('running by foo2.');
}
console.log('function foo2 spent time: ', getFunctionExecuteTime(foo2));
console.log('function foo spent time: ', getFunctionExecuteTime(foo));
console.log('function --- spent time: ', getFunctionExecuteTime(function(){
console.log('running.');
}));
})();
我想测试的那三个函数,它们的执行时间应该很接近,但是我得到的 Chrome 控制台的输出很有趣,如下所示:
由 foo2 运行。 function foo2 花费时间:5.1000000021304
运行。 function foo 花费时间:0.11000000085914508
运行。 函数---花费时间:0.115999995614402
即使我调换函数的顺序,第一个总是会花费更多的时间来执行,所以有人可以给我一个提示,告诉我到底发生了什么吗?
最佳答案
快速回答:
这是引擎 V8 优化 Javascript 代码的方式。
您的函数第一次运行时,Javascript 代码直接转换为机器代码,使其可以立即执行。
调用另一个线程来处理优化步骤。 Javascript 代码现在变成了中间字节码。
下次调用该函数时,将调用优化后的代码。
您可以阅读更多 here .
调查步骤:
这是我对 Node.js 环境的调查:
- 如果您像这样更改函数调用的顺序:
console.log('function foo spent time: ', getFunctionExecuteTime(foo));
console.log('function foo2 spent time: ', getFunctionExecuteTime(foo2));
结果:foo 的运行时间比 foo2 长。
running.
function foo spent time: 2.8903000000864267
running by foo2.
function foo2 spent time: 0.10759999975562096
running.
function --- spent time: 0.058200000785291195
- 有趣的部分是如果你运行这段代码:
const { performance } = require('perf_hooks');
const perf = () => {
const t1 = performance.now();
const t2 = performance.now();
return t2 - t1;
};
for (let i = 0; i < 10; i++) {
console.log(`Called ${i + 1} times. Time spent: ${perf()}`);
}
结果:同一个函数的第一次调用总是比其他调用花费更长的时间。
Called 1 times. Time spent: 0.4595999997109175
Called 2 times. Time spent: 0.026399999856948853
Called 3 times. Time spent: 0.018099999986588955
Called 4 times. Time spent: 0.0015000002458691597
Called 5 times. Time spent: 0.0015000002458691597
Called 6 times. Time spent: 0.0014000004157423973
Called 7 times. Time spent: 0.0021000001579523087
Called 8 times. Time spent: 0.0034999996423721313
Called 9 times. Time spent: 0.002199999988079071
Called 10 times. Time spent: 0.0027000000700354576
我想到了两件事:
- Node.js 的事件循环需要很短的时间来启动、条件检查...
- 或者是 V8 引擎(Chrome 和 Node.js 都使用它来编译 Javascript 代码)优化代码的方式。
所以,为了弄清楚,这里是对上面代码的一个小修改:
const { performance } = require('perf_hooks');
console.log('Waiting 1...');
console.log('Waiting 2...');
console.log('Waiting 3...');
console.log('Waiting 4...');
console.log('Waiting 5...');
const perf = () => {
const t1 = performance.now();
const t2 = performance.now();
return t2 - t1;
};
for (let i = 0; i < 10; i++) {
console.log(`Called ${i + 1} times. Time spent: ${perf()}`);
}
结果:
Waiting 1...
Waiting 2...
Waiting 3...
Waiting 4...
Waiting 5...
Called 1 times. Time spent: 0.8381999991834164
Called 2 times. Time spent: 0.00279999990016222
Called 3 times. Time spent: 0.0024000005796551704
Called 4 times. Time spent: 0.0026000002399086952
Called 5 times. Time spent: 0.00279999990016222
Called 6 times. Time spent: 0.0018000006675720215
Called 7 times. Time spent: 0.021200000308454037
Called 8 times. Time spent: 0.001600000075995922
Called 9 times. Time spent: 0.0014000004157423973
Called 10 times. Time spent: 0.001499999314546585
结论:
很明显,这就是 V8 引擎的工作方式。您的
getFunctionExecuteTime
函数在这里得到了优化。
关于javascript - 关于 performance.now() 来测试函数执行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31955069/