javascript - 关于 performance.now() 来测试函数执行时间

标签 javascript performance-testing performance.now

我目前正在自己​​创建一个简短的 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 代码的方式。

  1. 您的函数第一次运行时,Javascript 代码直接转换为机器代码,使其可以立即执行。

  2. 调用另一个线程来处理优化步骤。 Javascript 代码现在变成了中间字节码。

  3. 下次调用该函数时,将调用优化后的代码。

您可以阅读更多 here .

调查步骤:

这是我对 Node.js 环境的调查:

  1. 如果您像这样更改函数调用的顺序:
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
  1. 有趣的部分是如果你运行这段代码:
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
  1. 我想到了两件事:

    • 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
  1. 结论:

    很明显,这就是 V8 引擎的工作方式。您的 getFunctionExecuteTime 函数在这里得到了优化。

关于javascript - 关于 performance.now() 来测试函数执行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31955069/

相关文章:

javascript - 使用 JavaScript/JQuery 动态更改 CSS 字体

javascript - 如何使 CKeditor 所见即所得编辑器的拼写检查器工作

javascript - VueJS |根据选定的复选框或在输入字段中输入文本来过滤 API 数据

c# - WebTestRequest.ReportingName 在使用 VS 团队服务时被忽略

mysql - Jmeter:CSV数据在脚本中参数化但未在系统数据库中更新

javascript - Web Workers 中的 Performance.now() 可靠吗?

javascript - 我在哪里调用 performance.now() ?

javascript - D3.js svg.对 Angular 线问题

testing - WebServiceSampler : error in Jmeter