How can I benchmark JavaScript code?
有没有一个包可以帮助我对JavaScript代码进行基准测试? 我不是指Firebug和这样的工具。
我需要比较我实现的两个不同的JavaScript函数。 我非常熟悉Perl的Benchmark(Benchmark.pm)模块,我正在寻找类似JavaScript的东西。
是否强调对JavaScript代码进行基准测试? 我可以通过一次运行来计时吗?
jsperf.com是测试JS性能的首选站点。从那里开始。如果您需要一个框架来从命令行运行您自己的测试或脚本使用Benchmark.js,那么构建jsperf.com的库。
注意:任何测试Javascript代码的人都应该了解"微基准"的缺陷(针对特定功能或操作的小测试,而不是基于真实代码模式的更复杂的测试)。这些测试很有用,但由于现代JS运行时的运行方式,这些测试很容易出现不准确。 Vyacheslav Egorov关于性能和基准测试的演示值得关注,以了解问题的本质。
编辑:删除了对我的JSLitmus工作的引用,因为它不再相关或有用。
只需添加一个快速计时器,有人可能会觉得有用:
1 2 3 4 5 6 7 8 9 10 | 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'); } } }; |
理想情况下,它将被放置在一个类中,并不像上面的示例目的那样用作全局。使用它会很简单:
1 2 3 | var t = timer('Some label'); // code to benchmark t.stop(); // prints the time elapsed to the js console |
只需对每个函数进行多次迭代。一次迭代可能是不够的,但是(取决于你的函数有多复杂),接近100或甚至1000次迭代的地方应该可以完成这项任务。 del>
Firebug还有一个分析器,如果你想看看你的功能的哪些部分正在减慢它。 del>
编辑:对于未来的读者,推荐JSPerf的以下答案应该是正确的答案。我会删除我的,但我不能,因为它已被OP选中。基准测试不仅仅是运行多次迭代,而且JSPerf会为您完成这项工作。
简单的方法。
1 2 | console.time('test'); console.timeEnd('test'); |
我一直在使用@musicfreaks答案的这个简单实现。没有功能,但它真的很容易使用。该
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | /** * 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
如果您需要简单的东西,可以这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | '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) |
这是代码的一个例子