简体   繁体   English

您如何对 JavaScript 代码进行性能测试?

[英]How do you performance test JavaScript code?

CPU Cycles, Memory Usage, Execution Time, etc.? CPU 周期、Memory 使用情况、执行时间等?

Added: Is there a quantitative way of testing performance in JavaScript besides just perception of how fast the code runs?补充:JavaScript 中除了感知代码运行速度之外,是否有定量的方法来测试性能?

Profilers are definitely a good way to get numbers, but in my experience, perceived performance is all that matters to the user/client.探查器绝对是获取数字的好方法,但根据我的经验,感知性能对用户/客户来说是最重要的。 For example, we had a project with an Ext accordion that expanded to show some data and then a few nested Ext grids.例如,我们有一个带有 Ext 手风琴的项目,它可以扩展以显示一些数据,然后是一些嵌套的 Ext 网格。 Everything was actually rendering pretty fast, no single operation took a long time, there was just a lot of information being rendered all at once, so it felt slow to the user.一切其实都渲染得很快,没有一个操作需要很长时间,只是一次渲染了很多信息,所以用户感觉很慢。

We 'fixed' this, not by switching to a faster component, or optimizing some method, but by rendering the data first, then rendering the grids with a setTimeout.我们“修复”了这个问题,不是通过切换到更快的组件或优化某些方法,而是通过先渲染数据,然后使用 setTimeout 渲染网格。 So, the information appeared first, then the grids would pop into place a second later.因此,信息首先出现,然后网格会在下一秒后弹出。 Overall, it took slightly more processing time to do it that way, but to the user, the perceived performance was improved.总的来说,这样做需要更多的处理时间,但对用户来说,感知性能得到了改善。


These days, the Chrome profiler and other tools are universally available and easy to use, as are console.time() , console.profile() , and performance.now() .如今,Chrome 分析器和其他工具普遍可用且易于使用, console.time()console.profile()performance.now() Chrome also gives you a timeline view which can show you what is killing your frame rate, where the user might be waiting, etc. Chrome 还为您提供了一个时间线视图,它可以向您显示导致您的帧速率下降的因素、用户可能正在等待的位置等。

Finding documentation for all these tools is really easy, you don't need an SO answer for that.查找所有这些工具的文档非常简单,您不需要为此提供 SO 答案。 7 years later, I'll still repeat the advice of my original answer and point out that you can have slow code run forever where a user won't notice it, and pretty fast code running where they do, and they will complain about the pretty fast code not being fast enough. 7 年后,我仍然会重复我原来的答案的建议,并指出你可以让缓慢的代码在用户不会注意到的地方永远运行,而在他们所做的地方运行非常快的代码,他们会抱怨相当快的代码不够快。 Or that your request to your server API took 220ms.或者您对服务器 API 的请求花费了 220 毫秒。 Or something else like that.或者其他类似的东西。 The point remains that if you take a profiler out and go looking for work to do, you will find it, but it may not be the work your users need.重点仍然是,如果你拿出一个分析器去寻找工作要做,你会找到它,但它可能不是你的用户需要的工作。

I do agree that perceived performance is really all that matters.我确实同意感知性能真的很重要。 But sometimes I just want to find out which method of doing something is faster.但有时我只想找出做某事的哪种方法更快。 Sometimes the difference is HUGE and worth knowing.有时差异是巨大的,值得了解。

You could just use javascript timers.你可以只使用 javascript 计时器。 But I typically get much more consistent results using the native Chrome (now also in Firefox and Safari) devTool methods console.time() & console.timeEnd()但我通常使用原生 Chrome(现在也在 Firefox 和 Safari 中)devTool 方法console.time() & console.timeEnd()获得更一致的结果

Example of how I use it:我如何使用它的示例:

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

结果看起来像这样

Update (4/4/2016):更新 (4/4/2016):

Chrome canary recently added Line Level Profiling the dev tools sources tab which let's you see exactly how long each line took to execute! Chrome canary 最近添加了Line Level Profiling the dev tools sources 选项卡,让您准确了解每行执行所需的时间! 在此处输入图片说明

We can always measure time taken by any function by simple date object .我们总是可以通过简单的日期对象测量任何函数所花费的时间

var start = +new Date();  // log start timestamp
function1();
var end =  +new Date();  // log end timestamp
var diff = end - start;

Try jsPerf .试试jsPerf It's an online javascript performance tool for benchmarking and comparing snippets of code.它是一个在线 javascript 性能工具,用于对代码片段进行基准测试和比较。 I use it all the time.我用它所有的时间。

Most browsers are now implementing high resolution timing in performance.now() .大多数浏览器现在在performance.now()实现高分辨率计时。 It's superior to new Date() for performance testing because it operates independently from the system clock.它在性能测试方面优于new Date() ,因为它独立于系统时钟运行。

Usage用法

var start = performance.now();

// code being timed...

var duration = performance.now() - start;

References参考

JSLitmus is a lightweight tool for creating ad-hoc JavaScript benchmark tests JSlitmus是一个轻量级的工具,用于创建特别的 JavaScript 基准测试

Let examine the performance between function expression and function constructor :让我们检查function expressionfunction 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>

What I did above is create a function expression and function constructor performing same operation.我上面所做的是创建一个执行相同操作的function expressionfunction constructor The result is as follows:结果如下:

FireFox Performance Result FireFox 性能结果

FireFox 性能结果

IE Performance Result IE 性能结果

IE 性能结果

Some people are suggesting specific plug-ins and/or browsers.有些人建议使用特定的插件和/或浏览器。 I would not because they're only really useful for that one platform;我不会,因为它们只对那个平台真正有用; a test run on Firefox will not translate accurately to IE7.在 Firefox 上运行的测试不会准确地转换为 IE7。 Considering 99.999999% of sites have more than one browser visit them, you need to check performance on all the popular platforms.考虑到 99.999999% 的网站有多个浏览器访问它们,您需要检查所有流行平台的性能。

My suggestion would be to keep this in the JS.我的建议是将其保留在 JS 中。 Create a benchmarking page with all your JS test on and time the execution.创建一个包含所有 JS 测试和执行时间的基准测试页面。 You could even have it AJAX-post the results back to you to keep it fully automated.您甚至可以使用 AJAX 将结果发回给您,以使其完全自动化。

Then just rinse and repeat over different platforms.然后只需冲洗并在不同的平台上重复。

Here is a simple function that displays the execution time of a passed in function:这是一个简单的函数,用于显示传入函数的执行时间:

var perf = function(testName, fn) {
    var startTime = new Date().getTime();
    fn();
    var endTime = new Date().getTime();
    console.log(testName + ": " + (endTime - startTime) + "ms");
}

I have a small tool where I can quickly run small test-cases in the browser and immediately get the results:我有一个小工具,可以在浏览器中快速运行小测试用例并立即获得结果:

JavaScript Speed Test JavaScript 速度测试

You can play with code and find out which technique is better in the tested browser.您可以使用代码并找出在经过测试的浏览器中哪种技术更好。

I think JavaScript performance (time) testing is quite enough.我认为 JavaScript 性能(时间)测试已经足够了。 I found a very handy article about JavaScript performance testing here .我在这里找到了一篇关于JavaScript 性能测试的非常方便的文章。

You could use this: http://getfirebug.com/js.html .你可以使用这个: http : //getfirebug.com/js.html It has a profiler for JavaScript.它有一个用于 JavaScript 的分析器。

I was looking something similar but found this.我正在寻找类似的东西,但发现了这个。

https://jsbench.me/ https://jsbench.me/

It allows a side to side comparison and you can then also share the results.它允许进行横向比较,然后您还可以共享结果。

performance.mark (Chrome 87 ^) 性能标记(Chrome 87 ^)

performance.mark('initSelect - start');
initSelect();
performance.mark('initSelect - end');

在此处输入图片说明

Quick answer快速回答

On jQuery (more specifically on Sizzle), we use this (checkout master and open speed/index.html on your browser), which in turn uses benchmark.js .在 jQuery(更具体地说是在 Sizzle 上)上,我们使用(结帐大师并在浏览器上打开 speed/index.html),而后者又使用benchmark.js This is used to performance test the library.这用于对库进行性能测试。

Long answer长答案

If the reader doesn't know the difference between benchmark, workload and profilers, first read some performance testing foundations on the "readme 1st" section of spec.org .如果读者不知道基准测试、工作负载和分析器之间的区别,请首先阅读spec.org“自述文件 1”部分中的一些性能测试基础。 This is for system testing, but understanding this foundations will help JS perf testing as well.这是用于系统测试,但了解此基础也将有助于 JS 性能测试。 Some highlights:一些亮点:

What is a benchmark?什么是基准?

A benchmark is "a standard of measurement or evaluation" (Webster's II Dictionary).基准是“测量或评估的标准”(韦氏二词典)。 A computer benchmark is typically a computer program that performs a strictly defined set of operations - a workload - and returns some form of result - a metric - describing how the tested computer performed.计算机基准测试通常是一个计算机程序,它执行一组严格定义的操作——工作负载——并返回某种形式的结果——一个度量——描述被测试计算机的执行方式。 Computer benchmark metrics usually measure speed: how fast was the workload completed;计算机基准指标通常衡量速度:工作负载完成的速度; or throughput: how many workload units per unit time were completed.或吞吐量:每单位时间完成了多少工作负载单元。 Running the same computer benchmark on multiple computers allows a comparison to be made.在多台计算机上运行相同的计算机基准测试可以进行比较。

Should I benchmark my own application?我应该对自己的应用程序进行基准测试吗?

Ideally, the best comparison test for systems would be your own application with your own workload.理想情况下,系统的最佳比较测试是您自己的应用程序和您自己的工作负载。 Unfortunately, it is often impractical to get a wide base of reliable, repeatable and comparable measurements for different systems using your own application with your own workload.不幸的是,使用自己的应用程序和自己的工作负载为不同的系统获得可靠、可重复和可比较的广泛基础通常是不切实际的。 Problems might include generation of a good test case, confidentiality concerns, difficulty ensuring comparable conditions, time, money, or other constraints.问题可能包括生成好的测试用例、保密问题、难以确保可比较的条件、时间、金钱或其他限制。

If not my own application, then what?如果不是我自己的应用程序,那又是什么?

You may wish to consider using standardized benchmarks as a reference point.您可能希望考虑使用标准化基准作为参考点。 Ideally, a standardized benchmark will be portable, and may already have been run on the platforms that you are interested in. However, before you consider the results you need to be sure that you understand the correlation between your application/computing needs and what the benchmark is measuring.理想情况下,标准化的基准测试将是可移植的,并且可能已经在您感兴趣的平台上运行。但是,在考虑结果之前,您需要确保您了解应用程序/计算需求与应用程序/计算需求之间的相关性基准是衡量。 Are the benchmarks similar to the kinds of applications you run?基准测试是否与您运行的应用程序类型相似? Do the workloads have similar characteristics?工作负载是否具有相似的特征? Based on your answers to these questions, you can begin to see how the benchmark may approximate your reality.根据您对这些问题的回答,您可以开始了解基准测试如何接近您的实际情况。

Note: A standardized benchmark can serve as reference point.注:标准化基准可作为参考点。 Nevertheless, when you are doing vendor or product selection, SPEC does not claim that any standardized benchmark can replace benchmarking your own actual application.尽管如此,当您在进行供应商或产品选择时,SPEC 并不声称任何标准化的基准测试都可以替代您自己的实际应用的基准测试。

Performance testing JS性能测试JS

Ideally, the best perf test would be using your own application with your own workload switching what you need to test: different libraries, machines, etc.理想情况下,最好的性能测试是使用您自己的应用程序和您自己的工作负载切换您需要测试的内容:不同的库、机器等。

If this is not feasible (and usually it is not).如果这不可行(通常不可行)。 The first important step: define your workload.第一个重要步骤:定义您的工作负载。 It should reflect your application's workload.它应该反映您的应用程序的工作负载。 In this talk , Vyacheslav Egorov talks about shitty workloads you should avoid.本次演讲中,Vyacheslav Egorov 谈到了您应该避免的糟糕工作负载。

Then, you could use tools like benchmark.js to assist you collect metrics, usually speed or throughput.然后,您可以使用 benchmark.js 之类的工具来帮助您收集指标,通常是速度或吞吐量。 On Sizzle, we're interested in comparing how fixes or changes affect the systemic performance of the library.在 Sizzle 上,我们有兴趣比较修复或更改如何影响库的系统性能。

If something is performing really bad, your next step is to look for bottlenecks.如果某些东西的表现非常糟糕,那么下一步就是寻找瓶颈。

How do I find bottlenecks?如何找到瓶颈? Profilers探查器

What is the best way to profile javascript execution? 分析 javascript 执行的最佳方法是什么?

我发现执行时间是最好的衡量标准。

您可以在萤火虫中使用console.profile

Here is a reusable class for time performance.这是一个用于时间性能的可重用类。 Example is included in code:示例包含在代码中:

/*
     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

I usually just test javascript performance, how long script runs.我通常只是测试 javascript 性能,脚本运行多长时间。 jQuery Lover gave a good article link for testing javascript code performance , but the article only shows how to test how long your javascript code runs. jQuery Lover 提供了一个很好的文章链接,用于测试javascript 代码性能,但该文章仅展示了如何测试 javascript 代码运行多长时间。 I would also recommend reading article called "5 tips on improving your jQuery code while working with huge data sets".我还建议阅读名为“在处理大量数据集时改进 jQuery 代码的5 个技巧”的文章。

UX Profiler approaches this problem from user perspective. UX Profiler从用户的角度解决了这个问题。 It groups all the browser events, network activity etc caused by some user action (click) and takes into consideration all the aspects like latency, timeouts etc.它对由某些用户操作(点击)引起的所有浏览器事件、网络活动等进行分组,并考虑到延迟、超时等所有方面。

您可以使用https://github.com/anywhichway/benchtest将现有的 Mocha 单元测试与性能测试包装在一起。

The golden rule is to NOT under ANY circumstances lock your users browser.黄金法则是在任何情况下都不要锁定您的用户浏览器。 After that, I usually look at execution time, followed by memory usage (unless you're doing something crazy, in which case it could be a higher priority).之后,我通常会查看执行时间,然后是内存使用情况(除非你正在做一些疯狂的事情,在这种情况下它可能具有更高的优先级)。

Performance testing became something of a buzzword as of late but that's not to say that performance testing is not an important process in QA or even after the product has shipped.性能测试最近成为一个流行词,但这并不是说性能测试在 QA 中甚至在产品发货之后都不是一个重要的过程。 And while I develop the app I use many different tools, some of them mentioned above like the chrome Profiler I usually look at a SaaS or something opensource that I can get going and forget about it until I get that alert saying that something went belly up.当我开发应用程序时,我使用了许多不同的工具,其中一些工具如上面提到的chrome Profiler我通常会查看 SaaS 或一些开源的东西,我可以开始并忘记它,直到我收到警报,说有些事情发生了.

There are lots of awesome tools that will help you keep an eye on performance without having you jump through hoops just to get some basics alerts set up.有很多很棒的工具可以帮助您密切关注性能,而不必为了设置一些基本警报而跳过箍。 Here are a few that I think are worth checking out for yourself.这里有一些我认为值得自己检查的。

  1. Sematext.com Sematext.com
  2. Datadog.com数据狗网
  3. Uptime.com正常运行时间
  4. Smartbear.com智熊网
  5. Solarwinds.com Solarwinds.com

To try and paint a clearer picture, here is a little tutorial on how to set up monitoring for a react application.为了尝试绘制更清晰的图片, 这里有一个关于如何为 React 应用程序设置监控的小教程。

This is a very old question but I think we can contribute with a simple solution based on es6 for fast testing your code.这是一个非常古老的问题,但我认为我们可以贡献一个基于 es6 的简单解决方案来快速测试您的代码。

This is a basic bench for execution time .这是执行时间的基本工作台。 We use performance.now() to improve the accuracy:我们使用performance.now()来提高准确性:

 /** * Figure out how long it takes for a method to execute. * * @param {Function} method to test * @param {number} iterations number of executions. * @param {Array} list of set of args to pass in. * @param {T} context the context to call the method in. * @return {number} the time it took, in milliseconds to execute. */ const bench = (method, list, iterations, context) => { let start = 0 const timer = action => { const time = performance.now() switch (action) { case 'start': start = time return 0 case 'stop': const elapsed = time - start start = 0 return elapsed default: return time - start } }; const result = [] timer('start') list = [...list] for (let i = 0; i < iterations; i++) { for (const args of list) { result.push(method.apply(context, args)) } } const elapsed = timer('stop') console.log(`Called method [${method.name}] Mean: ${elapsed / iterations} Exec. time: ${elapsed}`) return elapsed } const fnc = () => {} const isFunction = (f) => f && f instanceof Function const isFunctionFaster = (f) => f && 'function' === typeof f class A {} function basicFnc(){} async function asyncFnc(){} const arrowFnc = ()=> {} const arrowRFnc = ()=> 1 // Not functions const obj = {} const arr = [] const str = 'function' const bol = true const num = 1 const a = new A() const list = [ [isFunction], [basicFnc], [arrowFnc], [arrowRFnc], [asyncFnc], [Array], [Date], [Object], [Number], [String], [Symbol], [A], [obj], [arr], [str], [bol], [num], [a], [null], [undefined], ] const e1 = bench(isFunction, list, 10000) const e2 = bench(isFunctionFaster, list, 10000) const rate = e2/e1 const percent = Math.abs(1 - rate)*100 console.log(`[isFunctionFaster] is ${(percent).toFixed(2)}% ${rate < 1? 'faster': 'slower'} than [isFunction]`)

This is a good way of collecting performance information for the specific operation.这是为特定操作收集性能信息的好方法。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM