使用Benchmark.js和jsPerf分析代码性能

标签: benchmark javascript jsperf | 发表时间:2015-08-24 16:30 | 作者:trigkit4
出处:http://segmentfault.com/blogs

前言

前端开发中,掌握好浏览器的特性进行有针对性的性能调优是一项基本工作,同时,比较不同代码的执行速度也是一项关键的工作。

比如,当我们想比较 RegExptest方法和 String对象的 indexOf方法查找字符串谁的速度更快的话, js代码在不同的浏览器,不同的操作系统环境运行的效率可能是不一样的,这就是为什么我们需要对其进行基准测试,在做基准测试方面,我们可以使用 Benchmark.js和使用 jsPerf(一个基于 JSLitmus的基准测试库)。我们可以使用 jsPerf来分享你的基准测试。

Benchmark.js 的使用

github 地址: https://github.com/bestiejs/benchmark.js

我们在很多 github 开源项目中,往往都能看到 benchmark文件夹,比如下面这个:

图片描述

于是 Google之,发现这是用来做基准测试的。于是乎:

首先我们在系统根目录下,通过 npm intsall benchmark 来安装 benchmark。该模块会被写入 node_modules文件夹中,我们在 test.js文件中通过 require方法引入该模块。

将如下代码写入 test.js文件,该文件置于系统根目录下:

  var Benchmark = require('benchmark');
var suite = new Benchmark.Suite;

// 添加测试
suite.add('RegExp#test', function() {
    /o/.test('Hello World!');
})
    .add('String#indexOf', function() {
        'Hello World!'.indexOf('o') > -1;
    })
// add listeners
    .on('cycle', function(event) {
        console.log(String(event.target));
    })
    .on('complete', function() {
        console.log('Fastest is ' + this.filter('fastest').pluck('name'));
    })
// run async
    .run({ 'async': true });

然后在终端执行 node test.js 可见输出结果如下:

  ➜  ~ git:(master) ✗ node test.js
RegExp#test x 9,847,928 ops/sec ±1.47% (83 runs sampled)
String#indexOf x 23,366,017 ops/sec ±0.91% (96 runs sampled)
Fastest is String#indexOf

结果最快的就是 String对象的 indexOf方法,其中, Ops/sec 测试结果以每秒钟执行测试代码的次数( Ops/sec)显示,这个数值越大越好。除了这个结果外,同时会显示测试过程中的统计误差,以及相对最好的慢了多少(%)

call和apply的比较

  var Benchmark = require('benchmark');
var suite = new Benchmark.Suite;
var arr1 = function (str) {
    return [].slice.apply(str);
};
var str2 = function (str) {
    return [].slice.call(str);
};
// 添加测试
suite.add('arr1', function() {
    arr1('test');
})
    .add('str2', function() {
        str2('test');
    })
// add listeners
    .on('cycle', function(event) {
        console.log(String(event.target));
    })
    .on('complete', function() {
        console.log('Fastest is ' + this.filter('fastest').pluck('name'));
    })
// run async
    .run({ 'async': true });

输出如下内容:

  arr1 x 596,505 ops/sec ±1.14% (95 runs sampled)
str2 x 627,822 ops/sec ±1.27% (92 runs sampled)
Fastest is str2

jsPerf 的使用

jsPerf 提供了一个简便的方式来创建和共享测试用例,并可以比较不同 JavaScript代码段的性能。 jsPerf也是基于 Benchmark来运行的。

打开 jsPerf站点: http://jsperf.com/,先将必填的项目填了。其中, slug是短名称,会生成一个网址,因此不可与别人的重复。然后在 Code snippets to compare 区域填入 title和用于测试的code。最后点击 save test case 完成验证即可。浏览器会自动跳转到测试页面

Async选项框是用来测试一些异步调用的性能的,我们的代码没有使用异步方法,所以不必勾选。

运行测试

点击“ Run tests”按钮开始测试两种算法的性能。建议在运行性能测试之前,关闭无关的浏览器页面,关闭其他程序,退出不必要的后台进程,以保证结果不受其他环境的影响。你也可以通过点击个别测试用例的名字单独运行这个例子

点击该链接查看性能比较: http://jsperf.com/huang

jsPerf还会统计所有运行过这个测试用例的浏览器的比较结果,显示在下方的 Browserscope区域,可以通过它直观地看出各个版本浏览器的性能横向和纵向比较情况。

图片描述

可以看到 Firefox下的执行速度明显高于 Chrome

查看别人的测试用例

我们可以通过 http://jsperf.com/browse 浏览最新提交的250项最新测试用例。我们也可以使用底部的 Revisions来查看不同的版本,也就是不同浏览器的测试用例情况。

总结

John Resig 在其博文 JavaScript 基准测试的质量 中提到,应该尽量考虑到每个测试结果的误差并去减小它。扩大测试的样本值,健全的测试执行,都能够起到减少误差的作用。

相关 [benchmark js jsperf] 推荐:

压力测试工具Benchmark

- - 企业架构 - ITeye博客
已有 0 人发表留言,猛击->> 这里<<-参与讨论. —软件人才免语言低担保 赴美带薪读研.

使用Benchmark.js和jsPerf分析代码性能

- - SegmentFault 最新的文章
前端开发中,掌握好浏览器的特性进行有针对性的性能调优是一项基本工作,同时,比较不同代码的执行速度也是一项关键的工作. 比如,当我们想比较 RegExp的 test方法和 String对象的 indexOf方法查找字符串谁的速度更快的话, js代码在不同的浏览器,不同的操作系统环境运行的效率可能是不一样的,这就是为什么我们需要对其进行基准测试,在做基准测试方面,我们可以使用 Benchmark.js和使用 jsPerf(一个基于 JSLitmus的基准测试库).

为什么说很多NoSQL的Benchmark是扯淡?

- 三十不归 - NoSQLFan
正如原作者所言,本文有标题党之嫌,但确实道出了一个众所周知的问题. 就是很多NoSQL产品的官方 benchmark 过高. 虽然本人并不完全同意作者的观点,但是其不盲从轻信较劲的态度还是值得学习. 抱歉我用了这么一个标题党的题目做为标题. 写这篇文章只是想引起大家的注意:在选择NoSQL产品时,达到标称性能,需要诸多限制条件,例如本文主要讨论的磁盘I/O.

HTC Jetstream 默默在 AT&T 上架 ,Benchmark 结果出炉!

- vic - Engadget 中国版
考虑来块 HTC Jetstream 平板吗. 就在你考虑的同时,它已于周末悄悄溜进 AT&T 的在线商店了,且绑约两年还要花费约 US$700(约 4469 元人民币). 所以我们诚心建议在您准备下手这台号称「提供消费者前所未有高价新体验」的平板产品前,可以先看看一些关于此机型的 Benchmark 比较表后再入手也不迟.

Go 生态圈的 K/V 数据库 benchmark

- - 鸟窝
Go生态圈有好几个K/V数据库,我们经常用它来做我们的存储引擎,但是这些数据库引擎的性能如何呢. 本文试图用性能而不是功能的数据考察这些数据库,我测试了几种场景: 并发写、并发读、单一写并发读、并发删除,得出了一些有趣的数据. 测试在两台机器上测试的,一台机械硬盘,一台固态硬盘,使用256字节作为value值的大小,9个字节作为key的大小,测试简单的读写删除操作,并没有测试批量读写操作.

WebView JS 交互

- - ITeye博客
WebView加jquery做页面会怎么样呢. // 创建WebView对象. // 把programList添加到js的全局对象window中,. // 这样就可以使用window.programList来获取数据. * 定义js回调java函数. // 绑定键盘的向上,向下按钮事件触发相应的js事件.

已经有 iPhone 4S 的 benchmark 看了,频率表现就只有约 800 MHz?

- tossking - Engadget 中国版
正当全世界都在等第一批 iPhone 4S 发货的时候,在世界的某些角落里已经有人拿到 iPhone 4S 来跑 benchmark 了(至少是拿到数据吧). 就跑 Javascript 的而言,4S 的表现与使用 Tegra 2 作为核心的 Samsung Galaxy Tab 8.9 难分高下,两者数据几乎一样;与 iPhone 4 (iOS 5 GM 版本)比较时表现则好约一倍.

JS游戏引擎

- 米随随 - HTML5研究小组
If you don’t have anything better to do and want to help fellow redditors interested in JS game dev out, feel free to fork the list and modify it as you like.

來源請求.js

- 红烧鲤鱼 - Blog: timdream
很早以前就想講了,但講了大概又會被戰. 相較於英文維基百科,中文維基百科在社會和歷史條目充滿了 systemic bias. 但是那些主觀論述又不是編輯者有意加進去的,而是某種編輯者存在的社會所給予的暗示(Inception?)與集體共識,而不是原本百科全書應該有的可驗證的事實. 因為是暗示又是共識,所以有自覺的百科編輯者反而是少數;中文維基只好長成現在這個樣子了.

Js删除节点

- - JavaScript - Web前端 - ITeye博客
 方式一:传this参数调用方法:.  方式二:js方法中通过选择器获取节点:. //此处删除的是a节点 }. 方式三:通过jQuery方式获取节点:(尚未测试,有待测试. 此处a标签传this到js中,js通过this(即a节点)取parent(即p节点). (1)p.remove();可直接删除整个p节点.