详解关于JSON.parse()和JSON.stringify()的性能小测试


Posted in Javascript onMarch 14, 2019

JSON.parse(JSON.stringify(obj))我们一般用来深拷贝,其过程说白了,就是利用 JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反序列化(还原)js对象。至于这行代码为什么能实现深拷贝,以及它有什么局限性等等,不是本文要介绍的。本文要探究的是,这行代码的执行效率如何?如果随意使用会不会造成一些问题?

先上两个js性能测试的依赖函数

/**
 * 一个简单的断言函数
 * @param value {Boolean} 断言条件
 * @param desc {String} 一个消息
 */
function assert(value, desc) {
  let li = document.createElement('li');
  li.className = value ? 'pass' : 'fail';
  li.appendChild(document.createTextNode(desc));
  document.getElementById('results').appendChild(li);
}
/**
 * 一个测试套件,定时器是为了多次执行减少误差
 * @param fn {Function} 需要多次执行的代码块(需要测试、比对性能的代码块)
 * @param config {Object} 配置项,maxCount: 执行代码块的for循环次数,times: 定时器执行次数
 */
function intervalTest(fn, config = {}) {
  let maxCount = config.maxCount || 1000;
  let times = config.times || 10;
  let timeArr = [];
  let timer = setInterval(function () {
    let start = new Date().getTime();
    for (let i = 0; i < maxCount; i++) {
      fn.call(this);
    }
    let elapsed = new Date().getTime() - start;
    assert(true, 'Measured time: ' + elapsed + ' ms');
    timeArr.push(elapsed);
    if (timeArr.length === times) {
      clearInterval(timer);
      let average = timeArr.reduce((p, c) => p + c) / times;
      let p = document.createElement('p');
      p.innerHTML = `for循环:${maxCount}次,定时器执行:${times}次,平均值:${average} ms`;
      document.body.appendChild(p);
    }
  }, 1000);
}

定义一些初始数据

let jsonData = {
  title: 'hhhhh',
  dateArr: [],
  series: [
    {
      name: 'line1',
      data: []
    },
    {
      name: 'line2',
      data: []
    },
    {
      name: 'line3',
      data: []
    },
  ]
};

let res = [
  {
    name: 'line1',
    value: 1
  },
  {
    name: 'line2',
    value: 2
  },
  {
    name: 'line3',
    value: 3
  },
];

场景1:模拟真实环境中图表数据实时更新

数据处理函数

/**
 * 处理json数据的函数。模拟真实环境中图表数据实时更新
 * @param lastData {Object} 上一次的数据
 * @param res {Array} 当前数据
 * @returns data 处理完成后的结果集
 */
function handleJsonData(lastData, res) {
  // 1. 使用 JSON.parse(JSON.stringify()) 深拷贝
  let data = JSON.parse(JSON.stringify(lastData));

  // 2. 不使用JSON序列化,直接修改参数
  // let data = lastData;

  if (data.dateArr.length > 60) {
    data.dateArr.shift();
    for (let i = 0; i < data.series.length; i++) {
      data.series[i].data.shift();
    }
  }
  data.dateArr.push(new Date().toTimeString().substr(0, 8));
  for (let i = 0; i < data.series.length; i++) {
    data.series[i].data.push(res[i].value);
  }
  return data;
}

maxCount=100

跑起来,先让maxCount=100,for循环100次

let jsonTest = function () {
  jsonData = handleJsonData(jsonData, res);
};

intervalTest(jsonTest, {maxCount: 100});

1.使用 JSON.parse(JSON.stringify()) 深拷贝 的结果:

详解关于JSON.parse()和JSON.stringify()的性能小测试

2.不使用JSON序列化,直接修改参数 的结果:

function handleJsonData(lastData, res) {
  // 1. 使用 JSON.parse(JSON.stringify()) 深拷贝
  // let data = JSON.parse(JSON.stringify(lastData));

  // 2. 不使用JSON序列化,直接修改参数
  let data = lastData;
  
  // ...
}

详解关于JSON.parse()和JSON.stringify()的性能小测试

maxCount=1000

intervalTest(jsonTest, {maxCount: 1000});

1.使用 JSON.parse(JSON.stringify()) 深拷贝 的结果:

详解关于JSON.parse()和JSON.stringify()的性能小测试

2.不使用JSON序列化,直接修改参数 的结果:

详解关于JSON.parse()和JSON.stringify()的性能小测试

maxCount=10000

intervalTest(jsonTest, {maxCount: 10000});

1.使用 JSON.parse(JSON.stringify()) 深拷贝 的结果:

详解关于JSON.parse()和JSON.stringify()的性能小测试

2.不使用JSON序列化,直接修改参数 的结果:

详解关于JSON.parse()和JSON.stringify()的性能小测试

场景2:判断一个对象是否为空对象

// 1. 使用 JSON.stringify() 判断一个对象是否为空对象
let isEmptyObject1 = function () {
  if (JSON.stringify(jsonData) === '{}') {
    // do something
  }
};

// 2. 使用 Object.keys().length 判断一个对象是否为空对象
let isEmptyObject2 = function () {
  if (Object.keys(jsonData).length === 0) {
    // do something
  }
};

只是走了一下判断条件,if内部没有执行代码

maxCount=1000

1.使用 JSON.stringify() 判断一个对象是否为空对象 的结果:

intervalTest(isEmptyObject1, {maxCount: 1000});

详解关于JSON.parse()和JSON.stringify()的性能小测试

2.使用 Object.keys().length 判断一个对象是否为空对象 的结果:

intervalTest(isEmptyObject2, {maxCount: 1000});

详解关于JSON.parse()和JSON.stringify()的性能小测试

maxCount=10000

1.使用 JSON.stringify() 判断一个对象是否为空对象 的结果:

详解关于JSON.parse()和JSON.stringify()的性能小测试

2.使用 Object.keys().length 判断一个对象是否为空对象 的结果:

详解关于JSON.parse()和JSON.stringify()的性能小测试

maxCount=100000

1.使用 JSON.stringify() 判断一个对象是否为空对象 的结果:

详解关于JSON.parse()和JSON.stringify()的性能小测试

2.使用 Object.keys().length 判断一个对象是否为空对象 的结果:

详解关于JSON.parse()和JSON.stringify()的性能小测试

关于JSON.parse()和JSON.stringify()的测试先到此为止,变换参数、更改执行的代码块可能会有不同结果,以上结果仅供参考。

小结论:能不用JSON.parse()和JSON.stringify()就不用,采用替代方案且性能更优的。PS:特别是需要多次执行的代码块,特别是这个JSON数据比较庞大时

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript中的Array对象使用说明
Jan 17 Javascript
动态加载js、css等文件跨iframe实现
Feb 24 Javascript
纯js实现仿QQ邮箱弹出确认框
Apr 29 Javascript
学习JavaScript设计模式(链式调用)
Nov 26 Javascript
vue.js实现请求数据的方法示例
Feb 07 Javascript
javascript设计模式之模块模式学习笔记
Feb 15 Javascript
jQuery事件_动力节点Java学院整理
Jul 05 jQuery
laravel5.4+vue+element简单搭建的示例代码
Aug 29 Javascript
JS中的Replace()传入函数时的用法详解
Sep 11 Javascript
vue如何自动化打包测试环境和正式环境的dist/test文件
Jun 06 Javascript
JS遍历树层级关系实现原理解析
Aug 31 Javascript
一定要知道的 25 个 Vue 技巧
Nov 02 Vue.js
详解使用React制作一个模态框
Mar 14 #Javascript
JavaScript碎片—函数闭包(模拟面向对象)
Mar 13 #Javascript
详解js动态获取浏览器或页面等容器的宽高
Mar 13 #Javascript
详解jQuery-each()方法
Mar 13 #jQuery
详解使用Nuxt.js快速搭建服务端渲染(SSR)应用
Mar 13 #Javascript
react同构实践之实现自己的同构模板
Mar 13 #Javascript
使用Node.js实现一个多人游戏服务器引擎
Mar 13 #Javascript
You might like
一个域名查询的程序
2006/10/09 PHP
我的论坛源代码(十)
2006/10/09 PHP
PHP设计模式之解释器模式的深入解析
2013/06/13 PHP
ThinkPHP CURD方法之where方法详解
2014/06/18 PHP
Yii框架中 find findAll 查找出制定的字段的方法对比
2014/09/10 PHP
php获取文章上一页与下一页的方法
2014/12/01 PHP
php使用ftp实现文件上传与下载功能
2017/07/21 PHP
phpinfo无法显示的原因及解决办法
2019/02/15 PHP
javascript获取网页中指定节点的父节点、子节点的方法小结
2013/04/24 Javascript
搭建pomelo 开发环境
2014/06/24 Javascript
js如何判断输入字符串长度
2015/12/16 Javascript
javascript的列表切换【实现代码】
2016/05/03 Javascript
前端js文件合并的三种方式推荐
2016/05/19 Javascript
关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)
2016/12/14 Javascript
微信小程序 仿美团分类菜单 swiper分类菜单
2017/04/12 Javascript
Node.JS文件系统解析实例详解
2017/05/15 Javascript
js中json对象和字符串的理解及相互转化操作实现方法
2017/09/22 Javascript
详解使用路由延迟加载 Angular 模块
2017/10/12 Javascript
vue.js中父组件调用子组件的内部方法示例
2017/10/22 Javascript
Vue.js项目中管理每个页面的头部标签的两种方法
2018/06/25 Javascript
vue中如何去掉空格的方法实现
2018/11/09 Javascript
使用puppeteer爬取网站并抓出404无效链接
2018/12/20 Javascript
浅谈JavaScript闭包
2019/04/09 Javascript
使用vue自定义指令开发表单验证插件validate.js
2019/05/23 Javascript
js 实现watch监听数据变化的代码
2019/10/13 Javascript
Vue.js 无限滚动列表性能优化方案
2019/12/02 Javascript
微信小程序实现音频文件播放进度的实例代码
2020/03/02 Javascript
python算法表示概念扫盲教程
2017/04/13 Python
Python装饰器用法实例总结
2018/05/26 Python
python dict 相同key 合并value的实例
2019/01/21 Python
python3中类的继承以及self和super的区别详解
2019/06/26 Python
Django实现简单网页弹出警告代码
2019/11/15 Python
会计电算化大学生职业规划书
2014/02/05 职场文书
工作违纪检讨书
2014/02/17 职场文书
大学四年个人总结
2015/03/03 职场文书
MySQL数据库之存储过程 procedure
2022/06/16 MySQL