你如何对 JavaScript 代码进行性能测试?
Posted
技术标签:
【中文标题】你如何对 JavaScript 代码进行性能测试?【英文标题】:How do you performance test JavaScript code? 【发布时间】:2010-09-11 19:13:05 【问题描述】:CPU 周期、内存使用、执行时间等?
补充:除了对代码运行速度的感知之外,是否有量化的方法来测试 javascript 的性能?
【问题讨论】:
您可能想查看 Firefox 的 YSlow 插件。 这只会告诉您加载需要多长时间。我认为这个问题更关心运行时的性能。 为了在浏览器中进行快速简单的测试,您可以使用jsben.ch 【参考方案1】:performance.mark (Chrome 87 ^)
performance.mark('initSelect - start');
initSelect();
performance.mark('initSelect - end');
【讨论】:
【参考方案2】:您可以使用https://github.com/anywhichway/benchtest,它将现有的 Mocha 单元测试与性能测试结合起来。
【讨论】:
【参考方案3】:性能测试最近成为了一个流行词,但这并不是说性能测试在 QA 中甚至在产品发货之后都不是一个重要的过程。当我开发应用程序时,我使用了许多不同的工具,其中一些像上面提到的 chrome Profiler 我通常会查看 SaaS 或开源的东西,我可以开始并忘记它,直到我收到警告说有什么东西出了问题起来。
有许多很棒的工具可以帮助您密切关注性能,而不必为了设置一些基本警报而费尽心思。以下是我认为值得您自己检查的一些内容。
-
Sematext.com
Datadog.com
Uptime.com
Smartbear.com
Solarwinds.com
为了尝试画出更清晰的画面,here 是一个关于如何为 React 应用程序设置监控的小教程。
【讨论】:
【参考方案4】:我正在寻找类似的东西,但发现了这个。
https://jsbench.me/
它允许横向比较,然后您还可以分享结果。
【讨论】:
【参考方案5】:分析器绝对是获取数字的好方法,但根据我的经验,感知性能对用户/客户来说才是最重要的。例如,我们有一个带有 Ext 手风琴的项目,它展开以显示一些数据,然后是一些嵌套的 Ext 网格。实际上一切都渲染得很快,没有一个操作需要很长时间,只是一次渲染了很多信息,所以用户感觉很慢。
我们“修复”了这个问题,不是通过切换到更快的组件或优化某些方法,而是通过先渲染数据,然后使用 setTimeout 渲染网格。因此,信息首先出现,然后网格会在一秒钟后出现。总体而言,这样做需要更多的处理时间,但对用户而言,感知性能得到了改善。
如今,Chrome 分析器和其他工具普遍可用且易于使用,console.time()
、console.profile()
和 performance.now()
也是如此。 Chrome 还为您提供时间线视图,它可以向您显示导致帧速率下降的原因、用户可能在哪里等待等。
查找所有这些工具的文档非常简单,您不需要 SO 答案。 7 年后,我仍然会重复我最初答案的建议,并指出您可以让慢代码在用户不会注意到的地方永远运行,而在他们注意到的地方运行相当快的代码,他们会抱怨相当快的代码不够快。或者您对服务器 API 的请求花费了 220 毫秒。或者其他类似的东西。重点仍然是,如果您拿出分析器并寻找工作要做,您会找到它,但它可能不是您的用户需要的工作。
【讨论】:
在众所周知的高性能算法到位之后,这是一个微调步骤。 这是一个非常好的答案,因为它对问题描述的大多数情况采取了实用的方法。但是,它没有回答问题,即询问是否有其他方法来衡量这一点,而不仅仅是用户感知。整个停机时间,例如按钮被冻结时,仍然可以使用 pramodc 答案中的方法和附加的 cmets 来测量。【参考方案6】:我有一个小工具,可以在浏览器中快速运行小型测试用例并立即获得结果:
JavaScript Speed Test
您可以玩代码并找出在测试浏览器中哪种技术更好。
【讨论】:
谢谢,这正是我想要的。【参考方案7】:这是一个简单的函数,显示传入函数的执行时间:
var perf = function(testName, fn)
var startTime = new Date().getTime();
fn();
var endTime = new Date().getTime();
console.log(testName + ": " + (endTime - startTime) + "ms");
【讨论】:
【参考方案8】:我同意感知性能确实是最重要的。但有时我只是想找出哪种方法更快。有时差异是巨大的,值得了解。
您可以只使用 javascript 计时器。但我通常使用原生 Chrome(现在也在 Firefox 和 Safari 中)devTool 方法 console.time()
和 console.timeEnd()
获得更一致的结果。
我如何使用它的示例:
var iterations = 1000000;
console.time('Function #1');
for(var i = 0; i < iterations; i++ )
functionOne();
;
console.timeEnd('Function #1')
console.time('Function #2');
for(var i = 0; i < iterations; i++ )
functionTwo();
;
console.timeEnd('Function #2')
更新(2016 年 4 月 4 日):
Chrome canary 最近添加了Line Level Profiling 开发工具源选项卡,让您可以准确查看每行执行的时间!
【讨论】:
是的,这个的魅力之一是它快速且易于实施。我想知道,日志记录本身是否会从 javascript 执行中获取一些性能。假设我们在游戏中有一个循环,它输出多个日志行。例如每秒一次,持续 5 分钟,即 300 行。有谁知道吗? 这还能用吗?不在 Chrome 中显示。 是的,仍然对我有用。 developer.chrome.com/devtools/docs/console-api#consoletimelabel @K.KilianLindberg 日志记录总是需要时间,就像任何代码一样,但是a)它会在你的测试中保持一致,b)你不应该在实时代码中进行控制台日志记录。在我的机器上测试后,时间记录只是 MS 的一小部分,但是你做的越多它就会累加。【参考方案9】:这是一个可重用的时间性能类。示例包含在代码中:
/*
Help track time lapse - tells you the time difference between each "check()" and since the "start()"
*/
var TimeCapture = function ()
var start = new Date().getTime();
var last = start;
var now = start;
this.start = function ()
start = new Date().getTime();
;
this.check = function (message)
now = (new Date().getTime());
console.log(message, 'START:', now - start, 'LAST:', now - last);
last = now;
;
;
//Example:
var time = new TimeCapture();
//begin tracking time
time.start();
//...do stuff
time.check('say something here')//look at your console for output
//..do more stuff
time.check('say something else')//look at your console for output
//..do more stuff
time.check('say something else one more time')//look at your console for output
【讨论】:
【参考方案10】:UX Profiler 从用户的角度来解决这个问题。它将由某些用户操作(点击)引起的所有浏览器事件、网络活动等进行分组,并考虑到延迟、超时等所有方面。
【讨论】:
【参考方案11】:我们总是可以通过简单的日期对象测量任何函数所花费的时间。
var start = +new Date(); // log start timestamp
function1();
var end = +new Date(); // log end timestamp
var diff = end - start;
【讨论】:
请注意,此解决方案以毫秒为单位返回差异 不鼓励使用 Date(),因为以毫秒为单位的时间可能会因系统因素而异。而是使用console.time() 和console.timeEnd()。有关详细信息,请参阅 JQuery Lover 的回答。 更好的是,使用performance.now()
在使用 performance.now() 之前请检查浏览器兼容性。 developer.mozilla.org/en-US/docs/Web/API/Performance/…
日期并不能真正代表过去的时间。看看这篇文章:sitepoint.com/measuring-javascript-functions-performance。 Performance.now() 是更准确的时间戳。【参考方案12】:
大多数浏览器现在都在performance.now()
中实现高分辨率计时。它在性能测试方面优于new Date()
,因为它独立于系统时钟运行。
用法
var start = performance.now();
// code being timed...
var duration = performance.now() - start;
参考文献
https://developer.mozilla.org/en-US/docs/Web/API/Performance.now() http://www.w3.org/TR/hr-time/#dom-performance-now【讨论】:
更好的是使用User Timing API,它基于performance.now()
。【参考方案13】:
快速解答
在 jQuery 上(更具体地说,在 Sizzle 上),我们使用 this(结帐大师并在您的浏览器上打开 speed/index.html),而后者又使用 benchmark.js。这用于对库进行性能测试。
长答案
如果读者不知道基准、工作负载和分析器之间的区别,请先阅读"readme 1st" section of spec.org 上的一些性能测试基础知识。这是用于系统测试的,但了解这些基础也将有助于 JS 性能测试。一些亮点:
什么是基准?
基准是“衡量或评估的标准”(韦氏词典)。计算机基准测试通常是一个计算机程序,它执行一组严格定义的操作 - 工作负载 - 并返回某种形式的结果 - 一个度量 - 描述测试计算机的执行情况。计算机基准指标通常衡量速度:工作负载完成的速度;或吞吐量:每单位时间完成了多少工作负载单元。在多台计算机上运行相同的计算机基准测试可以进行比较。
我应该对自己的应用程序进行基准测试吗?
理想情况下,对系统的最佳比较测试将是您自己的应用程序与您自己的工作负载。不幸的是,使用您自己的应用程序和您自己的工作负载,为不同系统获得广泛的可靠、可重复和可比较的测量结果通常是不切实际的。问题可能包括生成良好的测试用例、保密问题、难以确保可比较的条件、时间、金钱或其他限制。
如果不是我自己的应用程序,那又是什么?
您不妨考虑使用标准化基准作为参考点。理想情况下,标准化的基准测试将是可移植的,并且可能已经在您感兴趣的平台上运行。但是,在考虑结果之前,您需要确保您了解应用程序/计算需求与基准是衡量。基准测试是否与您运行的应用程序类型相似?工作负载是否具有相似的特征?根据您对这些问题的回答,您可以开始了解基准如何接近您的实际情况。
注意:标准化的基准可以作为参考点。然而,当您选择供应商或产品时,SPEC 并未声称任何标准化的基准测试都可以替代您自己的实际应用的基准测试。
性能测试 JS
理想情况下,最好的性能测试是使用您自己的应用程序和您自己的工作负载切换您需要测试的内容:不同的库、机器等。
如果这不可行(通常不可行)。第一个重要步骤:定义您的工作量。它应该反映您的应用程序的工作负载。在 this talk 中,Vyacheslav Egorov 谈到了您应该避免的糟糕工作负载。
然后,您可以使用 benchmark.js 等工具来帮助您收集指标,通常是速度或吞吐量。在 Sizzle 上,我们有兴趣比较修复或更改如何影响库的系统性能。
如果某件事的表现真的很糟糕,那么下一步就是寻找瓶颈。
如何找到瓶颈?分析器
What is the best way to profile javascript execution?
【讨论】:
【参考方案14】:这是收集特定操作的性能信息的好方法。
start = new Date().getTime();
for (var n = 0; n < maxCount; n++)
/* perform the operation to be measured *//
elapsed = new Date().getTime() - start;
assert(true,"Measured time: " + elapsed);
【讨论】:
【参考方案15】:你可以在 firebug 中使用console.profile
【讨论】:
【参考方案16】:JSLitmus 是用于创建即席 JavaScript 基准测试的轻量级工具
让我们检查function expression
和function constructor
之间的性能:
<script src="JSLitmus.js"></script>
<script>
JSLitmus.test("new Function ... ", function()
return new Function("for(var i=0; i<100; i++) ");
);
JSLitmus.test("function() ...", function()
return (function() for(var i=0; i<100; i++) );
);
</script>
我在上面所做的是创建一个 function expression
和 function constructor
执行相同的操作。结果如下:
FireFox 性能结果
IE 性能结果
【讨论】:
链接的 JSLitmus 页面包含损坏的下载链接。我找到了JSLitmus(用于浏览器)和jslitmus(用于NodeJS,小写!)。【参考方案17】:试试jsPerf。它是一个在线 javascript 性能工具,用于基准测试和比较代码的 sn-ps。我一直在使用它。
【讨论】:
由于 jsPerf 是 down at the moment,benchmarkjs 是 easy to use instead。 我也推荐它,因为它提供了 ops/sec 测量值(它会多次运行您的代码) +9001(超过九千;)用于 jsPerf。我经常在 Python 代码的ipython
REPL shell 中以与%timeit
类似的方式使用它。
不幸的是,这似乎不再可用:(【参考方案18】:
你可以使用这个:http://getfirebug.com/js.html。它有一个 JavaScript 分析器。
【讨论】:
【参考方案19】:我认为 JavaScript 性能(时间)测试已经足够了。我找到了一篇关于JavaScript performance testing here 的非常方便的文章。
【讨论】:
【参考方案20】:我通常只测试 javascript 性能,脚本运行多长时间。 jQuery Lover 提供了一个很好的文章链接来测试javascript code performance,但是文章只展示了如何测试你的 javascript 代码运行多长时间。我还建议阅读题为“处理大型数据集时improving your jQuery code 的 5 个技巧”的文章。
【讨论】:
【参考方案21】:有些人建议使用特定的插件和/或浏览器。我不会,因为它们只是真正对那个平台有用;在 Firefox 上运行的测试不会准确地转换为 IE7。考虑到 99.999999% 的网站有多个浏览器访问它们,您需要检查所有流行平台的性能。
我的建议是将其保留在 JS 中。创建一个基准测试页面,其中包含所有 JS 测试并计时执行。您甚至可以让它通过 AJAX 将结果返回给您,以保持它完全自动化。
然后只需冲洗并在不同平台上重复。
【讨论】:
这是真的,但如果出现与浏览器特定问题无关的编码问题,分析器会很好。 当然!是的,他们会发现一般的“糟糕的编码”问题,而特定的问题非常适合进行实际调试,但对于一般用例测试,您将从在所有平台上运行的东西中受益。 +1 请注意,这是真的,但是拥有像 Firebug 这样的分析器仍然很好,即使不是必不可少的,也可以找到瓶颈。 "考虑到 99.999999% 的网站..." 我认为你编造了... :-/ @RobG 我可能夸大了一两个小数位,但您的开发平台可能与您的部署平台不同的想法是成立的。【参考方案22】:我发现执行时间是最好的衡量标准。
【讨论】:
相对于什么?我不确定我是否理解。 与原始海报问题相反:“CPU 周期、内存使用情况、执行时间等?” CPU 周期,内存使用情况不好。【参考方案23】:黄金法则是在任何情况下都不要锁定您的用户浏览器。在那之后,我通常会查看执行时间,然后是内存使用情况(除非你正在做一些疯狂的事情,在这种情况下它可能是更高的优先级)。
【讨论】:
以上是关于你如何对 JavaScript 代码进行性能测试?的主要内容,如果未能解决你的问题,请参考以下文章