出人意料的性能测试

栏目: 编程工具 · 发布时间: 6年前

内容简介:在开发公司一次需求(就是一个3层或者4层嵌套的表单数据(都展示层输入框))的各种处理时,脑子灵光一闪,想到了一些提高性能的方案,但是苦于时间(其实是自己拖延),一直没有实际测试性能是否真的有提高。直到这几天才真正的去测试了一下,结果得出的结论出乎我的意料。测试嘛,数据肯定不能用公司的,但是要接近公司的真实数据量,二话不多上,直接上 Mock.js ,配置如下:上面配置只是简版的,实际开发中的数据还有很多其他信息,但是不影响我的测试。

在开发公司一次需求(就是一个3层或者4层嵌套的表单数据(都展示层输入框))的各种处理时,脑子灵光一闪,想到了一些提高性能的方案,但是苦于时间(其实是自己拖延),一直没有实际测试性能是否真的有提高。直到这几天才真正的去测试了一下,结果得出的结论出乎我的意料。

出人意料的性能测试

表单的数据结构

测试嘛,数据肯定不能用公司的,但是要接近公司的真实数据量,二话不多上,直接上 Mock.js ,配置如下:

{
    "data|4": [{
        "title": "@ctitle(5)",
        "content|25": [{
            "title": "@ctitle(5)",
            "content|25": [{
                "key": "@string(6)",
                "title": "@ctitle(5)",
                "value": "@word(3)"
            }]
        }]
    }]
}

复制代码

上面配置只是简版的,实际开发中的数据还有很多其他信息,但是不影响我的测试。

出人意料的性能测试

测试代码

看到数据结构可能很多老哥都猜到我要测啥了,我们在每次修改输入值的时候都要遍历数据,我们测的就是每次修改导致遍历数组所需要的时间。首先展示的代码如下:

renderForm(data) {
    return <>
      {
        data.map((item, index) => {
          return <div  className="yijimokuai">
            <h1>{item.title}</h1>
            {
              item.content.map((_item, _index) => {
                return <div  className="erjimokuai">
                  <h2>{_item.title}</h2>
                  {
                    _item.content.map((__item,__index) => {
                      return <div >
                        <span>{__item.title}:</span>
                        {/* <input type="text" value={__item.value} onChange={(e) => this.handleChange1(e,__item.key)}/> */}
                        {/* <input type="text" value={__item.value} onChange={(e) => this.handleChange2(e,__item.key)}/> */}
                        {/* <input type="text" value={__item.value} onChange={(e) => this.handleChange3(e,[index,_index,__index])}/> */}
                        <input type="text" value={this.state.dict[__item.key]} onChange={(e) => this.handleChange4(e,__item.key)}/>                      
                      </div>
                    })
                  }
                </div>
              })
            }
          </div>
        })
      }
    </>
  }

复制代码

有4种input,每种对应一个不同的Onchange方案:

  1. 方案1:没有优化
handleChange1(e,key){
    console.time('test1');
    let data = this.state.data;
    for (let i = 0,flen = data.length; i < flen ;i++) {
      for (let j = 0,slen = data[i].content.length; j< slen; j++) {
        for (let k = 0,klen = data[i].content[j].content.length; k< klen;k++) {
          if (data[i].content[j].content[k].key === key) {
            data[i].content[j].content[k].value = e.target.value
          }
        }
      }
    }
    this.setState({
      data
    },()=>{
      console.timeEnd('test1');
    })
  }
复制代码
  1. 方案2:最简单的,加个break
handleChange2(e,key){
    console.time('test2');
    let data = this.state.data;
    for (let i = 0,flen = data.length; i < flen ;i++) {
      for (let j = 0,slen = data[i].content.length; j< slen; j++) {
        for (let k = 0,klen = data[i].content[j].content.length; k< klen;k++) {
          if (data[i].content[j].content[k].key === key) {
            data[i].content[j].content[k].value = e.target.value
            break;
          }
        }
      }
    }
    this.setState({
      data
    },()=>{
      console.timeEnd('test2');
    })
  }
复制代码
  1. 方案3:直接传递数组下标
handleChange3(e,key) {
    console.time('test3');
    let data = this.state.data;
    data[key[0]].content[key[1]].content[key[2]].value = e.target.value;
    this.setState({
      data
    },() => {
      console.timeEnd('test3');
    })
  }
复制代码
  1. 方案4:把数组中的值拷贝一份出来做一个字典,每次改值都在字典中改
handleChange4(e,key){
    console.time('test4');
    let dict = this.state.dict;
    dict[key] = e.target.value;
    this.setState({
      dict
    },() => {
      console.timeEnd('test4');
    })
  }
复制代码

理论分析

理论上的时间复杂度 方案1、2不用说了其实都是一样的,O(n^3) 方案3理论上是O(1) 方案4理论上是O(n),且需要额外的空间复杂度O(n) 综合性能上的话应该是 方案3 > 方案4 > 方案2 > 方案1

开测

为了保证测试结果,每次都修改3个输入框的值,每次都是新增输入3个同样的字符,废话不多说,直接测

出人意料的性能测试

方案1

出人意料的性能测试

方案2:

出人意料的性能测试

方案3:

出人意料的性能测试

方案4:

出人意料的性能测试
出人意料的性能测试

纳尼?居然都差不多?

接下来用不同的浏览器测试,数据来源换成生成好的JSON(保住数据完全相同),增大数据量都试过,在浏览器不卡死能渲染的情况下,这几种情况下的渲染时间居然是不相上下。

分析

后来在每种方案调用的情况下都调用了一下console.time,发现4种方案消耗时间基本一致。就是说,方案1、2的遍历速度在我的电脑上遍历速度都非常快,导致了优化的效果并不明显。也就是说,在公司做的性能优化方案其实对于常见的电脑来说其实意义不大(测试的数据量已经大于公司的数据量了)。但是对于低端机器,又没有合适的 工具 可以进行测试。。。

后话

有心人可能发现我一开始的渲染代码中没有上key(故意删的),因为当React作diff时,只要子元素有key属性,便会去原v-dom树中相应位置(当前横向比较的层级)寻找是否有同key元素,比较它们是否完全相同,若是则复用该元素,免去不必要的操作。但是对于我们此种测试,上述操作反而是不必要的,因为我们数据是固定的,上key反而多做了一次遍历(上面说的都是我猜的原因),那么上了key之后的时间是多少呢?

出人意料的性能测试

想了那么久的数据结构,结果发现主流的电脑都可以忽略这点优化了,心情复杂。。。有没有大神告知一下是测试方法有问题还是真的机子太高端了,在这种数据级的情况下优化是没多大必要的?

出人意料的性能测试

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Persuasive Technology

Persuasive Technology

B.J. Fogg / Morgan Kaufmann / 2002-12 / USD 39.95

Can computers change what you think and do? Can they motivate you to stop smoking, persuade you to buy insurance, or convince you to join the Army? "Yes, they can," says Dr. B.J. Fogg, directo......一起来看看 《Persuasive Technology》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具