资讯专栏INFORMATION COLUMN

每日 30 秒 ⏱ 谁敢与我一战

Dionysus_go / 3127人阅读

简介
benchmark、基准测试、jsPerf

在 优雅插入数组 一文中大家最多的评论就是 “能不能加个基准测试”。小二不是不喜欢加基准测试而是现在硬件设备的性能越来越快了,有时候一些操作不是性能问题的主要原因,当然这不是我们不写出好代码的理由。

书写代码还是应该在 优雅易读运行性能中做出平衡,适合的场景做适合的事情。不过既然大家都提到了 基准测试 碰巧我又刚好没有想到要写什么那就一起了解一下 基准测试 吧。

人非圣贤孰能无过,三两八哥常伴吾身。-- 嗯是我

测试 在中大型和和开源项目中算是 必备内容,好测试可以在假定的场景下找到项目的错误帮助我们写出质量更好的代码,也是协作开发中的调和剂。测试 是一门开发中的大学问不是一篇文章就能讲得明白的。

Talk is cheap, Show me the code. -- Linus Torvalds

本文选择的 基准测试 只是 测试 中一个小分支,本文简单帮助大家涉猎一些简单的概念和测试工具。学习后当遇到野生程序猿说出骚话:“废话少说,放马过来”,请抄起键盘打开 基准测试 工具大喊:“吾乃燕人张翼德,谁敢与我一战?”

抛硬币

抛一次硬币就得到 出现正面概率是百分百 的结论显然是错误的,数学老师教过我们 大数定律:“需要数据量足够多、样本足够打才能下结论”。当抛均匀硬币次数足够多时出现正面概率应该无限趋近于百分五十,对照抛硬币实验 基准测试 一样不能只记录一次代码运行时间就可以得出结果的,需要进行足够多的次数。

吓螃蟹
科学家从笼子里抓出一只螃蟹,放在地上,冲着它大吼大叫,螃蟹被吓得不轻,到处乱窜,慌不择路。然后科学家把螃蟹的腿拆卸下来重复之前的步骤,继续大吼大叫,螃蟹一动不动,非常的淡定从容,得到结论螃蟹的耳朵是长在腿上的

这个小笑话大家应该都听过,没有考虑螃蟹逃跑是需要用腿。在做生物对照实验时出现的三个概念 自变量因变量无关变量,控制好它们从而得到真实的结果。基准测试的影响变量可以是手机进入省电模式带来的运行速度降低,可以是电脑正在运行无关软件导致某一时刻测试环境不一致,也是可以是代码初始状态的不一致例子如下:

// 代码一
let a = [1, 2, 3, 4];
a.push(5);

// 代码二
let b = [1, 2, 3, 4, 5, 6, 7, 8];
b = [...b, 9];

测试上面两个代码并不能得出谁的性能更好,因为初始数组的长度不一样存在数组越大操作越慢的情况。

Benchmark

上面简单两个例子帮助理解 基准测试 的一些基本要点。在开发中除了利用浏览器的特性来调优代码,有时候不同的代码写法也会带来不一样的性能表现。在 优雅插入数组 中把数据插入数组尾部就介绍了四种不一样的方法,利用哪一种写法会使得代码 优雅、易懂、跑得快呢,可以使用 Benchmark 来帮助测试得到结论。

安装
npm i --save benchmark
使用

add 接口添加测试代码。

on 接口插入代码到测试周期中。

run 运行代码。

例子
代码
let suite = new Benchmark.Suite;

suite
    .add("#1 利用数组长度进行赋值", () => {
        let arr = [1, 2, 3, 4, 5];
        arr[arr.length] = 6;
    })
    .add("#2 利用 Array.prototype.push 方法", () => {
        let arr = [1, 2, 3, 4, 5];
        arr.push(6);
    })
    .add("#3 利用 Array.prototype.concat 方法", () => {
        let arr = [1, 2, 3, 4, 5];
        arr = arr.concat(6);
    })
    .add("#4 利用 spread 运算符", () => {
        let arr = [1, 2, 3, 4, 5];
        arr = [...arr, 6];
    })
    .on("start", (event) => {
        // 在整个测试运行前
        console.log("把数据插入数组尾部");
    })
    .on("cycle", (event) => {
        // 每个测试代码运行后
        console.log(String(event.target));
    }).on("complete", () => {
        // 测试完成后
        console.log("最快方法是 " + suite.filter("fastest").map("name"));
    }).run({ "async": true })
输出
#1 利用数组长度进行赋值 x 3,590,121 ops/sec ±0.97% (87 runs sampled)
#2 利用 Array.prototype.push 方法 x 15,796,478 ops/sec ±0.61% (88 runs sampled)
#3 利用 Array.prototype.concat 方法 x 2,373,044 ops/sec ±1.00% (83 runs sampled)
#4 利用 spread 运算符 x 2,405,217 ops/sec ±0.72% (91 runs sampled)
最快方法是 #2 利用 Array.prototype.push 方法
jsPerf
A benchmarking library. As used on jsPerf.com.

在 Benchmark 仓库中的项目简介中提到了 jsPerf 一个基于 Benchmark 的便捷基准测试站点。使用 Github 登录后,按照创建表格中的数据填写就能生成基准测试

基准测试 例子 在 jsPerf 中链接为 数据插入数组尾部,利用 jsPerf 可以很方便的进行分享(就像现在),还可以在不同浏览器中打开测试。下面对页面名称进行简单翻译方便英语不好的同学使用:

个人信息
名词 解释
Your details 个人信息,可选填
Name 作者名字
Email 作者邮箱,由于生成头像
URL 项目地址
案例信息
名词 解释
Test case details 案例信息
Title 标题
Slug 网站 slug,会被拼接成 https://jsperf.com/slug
Description 项目描述
预加载
名词 解释
Preparation code 预加载
Preparation code HTML 项目需要的 DOM 结构 和 引入外部脚本
Define setup for all tests 每次测试前将会执行的操作即 Benchmark.setup 中的配置,例如初始化变量。
Define teardown for all tests 每次测试后会执行的操作即 Benchmark.teardown 中的配置,例如清除变量。
需要比较的代码段

如果有不需要的测试代码框只需要放空内容并保存就会自己删除。

名词 解释
Code snippets to compare 需要比较的代码段
Title 测试代码段标题
Async 代码段是否异步
Code 需要测试的代码
Add code snippet 添加测试代码
Save test case 保存
测试页面
名词 解释
Run test 运行测试
Testing in ... 测试所在的浏览器及其版本、操作系统及其版本
Ops/sec 每秒钟代码执行次数,数值越大越好
You can edit these tests or add even more tests to this page by appending /edit to the URL. 点击该链接可以修改测试代码,但是 slug 这些是改不了的
Compare results of other browsers 所有浏览器测试结果
Chart type 数据展示方式:条形图、折线图、饼图、表格
Filter 浏览器环境
结尾
还不赶紧带上键盘与野生程序员大战三百回合,打满经验升级飞仙成为上古程序员。
一起成长
在困惑的城市里总少不了并肩同行的 伙伴 让我们一起成长。

如果您想让更多人看到文章可以点个 点赞

如果您想激励小二可以到 Github 给个 小星星

如果您想与小二更多交流添加微信 m353839115

本文原稿来自 PushMeTop

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102886.html

相关文章

  • 每日 30 ⏱ 该不该优雅

    showImg(https://segmentfault.com/img/remote/1460000018734296?w=900&h=500); 简介 可读性、性能、Spread、Reduce 在 优雅三连击 中有同学提到了 可读性 这个关键词,就小二个人的观点 在某个范围内使用比较常用到的小技巧,可以提升一定的可读性,文中提到的短路运算在初始化变量是提升可读性的,并且在很多提倡优化if 语句...

    JohnLui 评论0 收藏0
  • yii实战之控制器与视图交互

    继上篇yii实战之初见端倪,本篇将讲解控制器和视图的基础用法。并构建一个人物列表页面 默认控制器 默认情况下,当浏览器请求http://frontend.test/时,实际上访问的是frontend/controllers/SiteController.php的actionIndex方法,我们在这个方法断点测试下: public function actionIndex() { retur...

    Riddler 评论0 收藏0
  • 每日 30 ⏱ 无障碍世界

    showImg(https://segmentfault.com/img/remote/1460000018836440); 简介 无障碍、DOM 小细节、前端开发、a11y、Accessibility 无障碍的英文为 Accessibility 由于单词拼写过长往往被缩写为 a11y 其中 11 指的是中间有11个字母。 无障碍指的是在使用过程中,不管什么类型的用户都可以正常使用。生活中最常见的...

    duan199226 评论0 收藏0
  • 每日 30 ⏱ 终极等于

    简介 字符串、数字、数组、对象、时间、类型、等于 科学家发现,人脑中会分泌多种能让人感到快乐、安全和成就感的物质,这些物质统称为快乐素。通常情况下,快乐素的释放水平很低,维持我们心情平静。只有当我们完成了预设目标,作为奖励,大脑才会增加快乐素的分泌,让人感受到满足和成功的喜悦。 这是之前看到的一篇关于 大脑奖励机制 文章的一段话,为了要获得奖励我们需要有预设目标,而是每日 30 秒系列也是为了帮助...

    lakeside 评论0 收藏0
  • 姆巴佩独造三球一战成名 阿里云打破世界杯流量纪录

    摘要:这个周末举行的俄罗斯世界杯决赛可谓精彩纷呈,高卢雄鸡和潘帕斯雄鹰上演进球大战,姆巴佩一人独造三粒进球一战成名,法国队比送阿根廷回家,梅西再度饮恨而归,另一边葡萄牙比不敌乌拉圭,梅西与罗两大超巨止步八强。 摘要: 这个周末举行的俄罗斯世界杯1/8决赛可谓精彩纷呈,高卢雄鸡和潘帕斯雄鹰上演进球大战,姆巴佩一人独造三粒进球一战成名,法国队4比3送阿根廷回家,梅西再度饮恨而归,另一边葡萄牙1比...

    aaron 评论0 收藏0

发表评论

0条评论

Dionysus_go

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<