有没有可以帮助我测试JavaScript代码的软件包?我指的不是Firebug和此类工具。
我需要比较已实现的2个不同的JavaScript函数。我对Perl的Benchmark(Benchmark.pm)模块非常熟悉,并且我正在寻找JavaScript中类似的东西。
对基准测试JavaScript代码的重视程度是否过高?我可以只对一项功能进行计时吗?
有没有可以帮助我测试JavaScript代码的软件包?我指的不是Firebug和此类工具。
我需要比较已实现的2个不同的JavaScript函数。我对Perl的Benchmark(Benchmark.pm)模块非常熟悉,并且我正在寻找JavaScript中类似的东西。
对基准测试JavaScript代码的重视程度是否过高?我可以只对一项功能进行计时吗?
Answers:
只需对每个函数进行几次迭代即可。一个迭代可能还不够,但是(取决于函数的复杂程度)大约100甚至1000个迭代应该可以完成工作。
如果您想查看功能的哪些部分在放慢速度,Firebug还提供了一个探查器。
编辑:对于将来的读者,建议JSPerf的以下答案应该是正确的答案。我会删除我的,但不能删除,因为OP已选择它。基准测试不仅仅是运行许多迭代,还有很多,JSPerf会为您解决这一问题。
jsperf.com是测试JS性能的首选站点。从那里开始。如果您需要一个框架来从命令行或脚本运行自己的测试,请使用Benchmark.js,即构建jsperf.com的库。
注意:任何测试Javascript代码的人都应该对“微基准”的陷阱进行自我教育(针对特定功能或操作的小型测试,而不是基于实际代码模式的更复杂的测试)。这样的测试可能有用,但由于现代JS运行时的运行方式而容易出错。 Vyacheslav Egorov关于性能和基准测试的演示值得一看,以了解问题的本质。
编辑:删除了对我的JSLitmus工作的引用,因为它不再相关或不再有用。
只需在混音中添加一个快速计时器,某人可能会觉得有用:
var timer = function(name) {
var start = new Date();
return {
stop: function() {
var end = new Date();
var time = end.getTime() - start.getTime();
console.log('Timer:', name, 'finished in', time, 'ms');
}
}
};
理想情况下,将其放置在一个类中,而不是像我上面示例中那样用作全局变量。使用它会非常简单:
var t = timer('Some label');
// code to benchmark
t.stop(); // prints the time elapsed to the js console
我一直在使用@musicfreaks答案的这种简单实现。没有功能,但是使用起来确实很容易。这bench(function(){return 1/2;}, 10000, [], this)
将计算1/2 10,000次。
/**
* Figure out how long it takes for a method to execute.
*
* @param {Function} method to test
* @param {number} iterations number of executions.
* @param {Array} args to pass in.
* @param {T} context the context to call the method in.
* @return {number} the time it took, in milliseconds to execute.
*/
var bench = function (method, iterations, args, context) {
var time = 0;
var timer = function (action) {
var d = Date.now();
if (time < 1 || action === 'start') {
time = d;
return 0;
} else if (action === 'stop') {
var t = d - time;
time = 0;
return t;
} else {
return d - time;
}
};
var result = [];
var i = 0;
timer('start');
while (i < iterations) {
result.push(method.apply(context, args));
i++;
}
var execTime = timer('stop');
if ( typeof console === "object") {
console.log("Mean execution time was: ", execTime / iterations);
console.log("Sum execution time was: ", execTime);
console.log("Result of the method call was:", result[0]);
}
return execTime;
};
编写像样的跨浏览器基准测试真的很困难。仅仅对代码的预定义迭代次数进行定时根本不是防弹的。
正如@broofa已经建议的那样,请查看jsPerf。它在后台使用Benchmark.js。
如果编写自定义基准脚本,请确保注意某些浏览器仅在定义它们的功能结束后才应用dom操作。更多详细信息, 请参见http://www.quirksmode.org/blog/archives/2009/08/when_to_read_ou.html
如果您需要简单的东西,可以这样做:
'use strict'
console.clear()
const powerOf = x => y => Math.pow(x, y)
const powerOfThree = powerOf(3)
function performanceCalc(fn, ...params) {
const start = +new Date()
const result = fn(...params)
const end = +new Date()
console.log(`Result: ${result}. Execution Time: ${end - start} ms`)
}
performanceCalc(powerOfThree, 2)