如何对JavaScript代码进行基准测试?[关闭]


104

有没有可以帮助我测试JavaScript代码的软件包?我指的不是Firebug和此类工具。

我需要比较已实现的2个不同的JavaScript函数。我对Perl的Benchmark(Benchmark.pm)模块非常熟悉,并且我正在寻找JavaScript中类似的东西。

对基准测试JavaScript代码的重视程度是否过高?我可以只对一项功能进行计时吗?




我知道这并不是全部,但还是有关系的:有时您只想知道如何衡量函数执行所需的时间
Skippy le Grand Gourou's

1
我是一个不错的JavaScript基准测试工具,您可以在这里找到:jsben.ch
EscapeNetscape

Answers:


36

只需对每个函数进行几次迭代即可。一个迭代可能还不够,但是(取决于函数的复杂程度)大约100甚至1000个迭代应该可以完成工作。

如果您想查看功能的哪些部分在放慢速度,Firebug还提供了一个探查器

编辑:对于将来的读者,建议JSPerf的以下答案应该是正确的答案。我会删除我的,但不能删除,因为OP已选择它。基准测试不仅仅是运行许多迭代,还有很多,JSPerf会为您解决这一问题。


12
仅仅对代码的预定义迭代次数进行定时根本不是防弹的。另外,打开Firebug会禁用Firefox的即时(JIT)编译器,这意味着测试将在解释器中运行,即比原本的速度要慢得多。使用Firebug的事件探查器无法获得预期的结果。
Mathias Bynens

1
@Mathias:好吧,公平地说,这个答案真的很老。
Sasha Chedygov

2
当然,没有冒犯的人。我只是想我要发表评论,以供将来参考,因为已经对该主题进行了更多研究。
Mathias Bynens

4
或使用jsben.ch,因为jsperf停止运行
EscapeNetscape

118

jsperf.com是测试JS性能的首选站点。从那里开始。如果您需要一个框架来从命令行或脚本运行自己的测试,请使用Benchmark.js,即构建jsperf.com的库。

注意:任何测试Javascript代码的人都应该对“微基准”的陷阱进行自我教育(针对特定功能或操作的小型测试,而不是基于实际代码模式的更复杂的测试)。这样的测试可能有用,但由于现代JS运行时的运行方式而容易出错。 Vyacheslav Egorov关于性能和基准测试的演示值得一看,以了解问题的本质。

编辑:删除了对我的JSLitmus工作的引用,因为它不再相关或不再有用。


3
更新:只需使用jsperf.com-它已经变得更好了,并且对于这种事情非常有效。jslitmus仍然可以工作,但是已经有一段时间没有积极开发了。
broofa 2011年

这是上乘的答案。+1
贾斯汀力

1
我想使用jsperf,但它似乎是在计算一段时间内可以运行代码的次数,而不是对N个循环的实际调用进行计时。我希望他们可以选择。
13年

1
@Jeach-jsperf给出“操作数/秒”。只需将该值乘以您要运行代码的时间(以秒为单位)即可。
broofa 2013年

4
更新:jsperf不再在线,并且何时恢复在线也没有任何消息。有关更多信息,请参见此github线程
James Gould

73

只需在混音中添加一个快速计时器,某人可能会觉得有用:

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

6
在这里很好地使用闭包。
丹迪

12
为了获得更准确的结果,可能要使用performance.now()而不是Date() developer.mozilla.org/en-US/docs/Web/API/Performance/now
thormeier

我需要的只是一个timeIt()
Gishu,2016年

1

1
对于node.js,您可以使用process.hrtime()获得纳秒分辨率。
Xeoncross '18年

56

只是简单的方法。

console.time('test');
console.timeEnd('test');

3
这应该是公认的答案。有时使用第三方服务并不方便,而仅使用简单的内置功能非常好。
脑袋

1
@brainbag-问题是基准测试,它涉及的不仅仅是简单地计时代码运行多长时间。此外,控制台计时器仅在所讨论的代码花费超过1毫秒(其分辨率的极限)时才有用。
broofa

您可能还想在测试套件中运行基准测试,该套件需要访问计时器值。
JamesDev

20

我一直在使用@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;  
};



1

如果您需要简单的东西,可以这样做:

'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)

这是代码示例


就我而言,简单无疑是最好的选择……编写一些测试以测试API的响应时间(不需要非常准确的时间)。
kashiraja
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.