详解关于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 相关文章推荐
怎么让脚本或里面的函数在所有图片都载入完毕的时候执行
Oct 17 Javascript
javascript 事件绑定问题
Jan 01 Javascript
扩展js对象数组的OrderByAsc和OrderByDesc方法实现思路
May 17 Javascript
JQuery的ready函数与JS的onload的区别详解
Nov 21 Javascript
随鼠标移动的时钟非常漂亮遗憾的是只支持IE
Aug 12 Javascript
JS动态创建DOM元素的方法
Jun 09 Javascript
JS实现鼠标滑过折叠与展开菜单效果代码
Sep 06 Javascript
angular2使用简单介绍
Mar 01 Javascript
JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome
Jan 05 Javascript
Vue打包后出现一些map文件的解决方法
Feb 13 Javascript
vue+iview动态渲染表格详解
Mar 19 Javascript
Vue 的双向绑定原理与用法揭秘
May 06 Javascript
详解使用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
PHP静态类
2006/11/25 PHP
php中将图片gif,jpg或mysql longblob或blob字段值转换成16进制字符串
2011/08/23 PHP
PHP IDE PHPStorm配置支持友好Laravel代码提示方法
2015/05/12 PHP
PHP面向对象程序设计内置标准类,普通数据类型转为对象类型示例
2019/06/12 PHP
PHP实现统计代码行数小工具
2019/09/19 PHP
jquery应该如何来设置改变按钮input的onclick事件
2012/12/10 Javascript
js中页面的重新加载(当前页面/上级页面)及frame或iframe元素引用介绍
2013/01/24 Javascript
Extjs实现进度条的两种便捷方式
2013/09/26 Javascript
Jquery1.9.1源码分析系列(六)延时对象应用之jQuery.ready
2015/11/24 Javascript
7个去伪存真的JavaScript面试题
2016/01/07 Javascript
浅谈JavaScript 数据属性和访问器属性
2016/09/01 Javascript
Bootstrap笔记—折叠实例代码
2017/03/13 Javascript
原生JS实现层叠轮播图
2017/05/17 Javascript
详解Angular-Cli中引用第三方库
2017/05/21 Javascript
vue脚手架搭建过程图解
2018/06/06 Javascript
微信小程序开发之点击按钮退出小程序的实现方法
2019/04/26 Javascript
vue项目中使用scss的方法步骤
2019/05/16 Javascript
解决vue cli使用typescript后打包巨慢的问题
2019/09/30 Javascript
js判断密码强度的方法
2020/03/18 Javascript
JavaScript事件循环及宏任务微任务原理解析
2020/09/02 Javascript
[02:36]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Magma 选手采访
2021/03/11 DOTA
python实现应用程序在右键菜单中添加打开方式功能
2017/01/09 Python
python之matplotlib学习绘制动态更新图实例代码
2018/01/23 Python
Python Flask基础教程示例代码
2018/02/07 Python
Html5上传图片 移动端、PC端通用代码
2016/06/08 HTML / CSS
Skyscanner英国:苏格兰的全球三大领先航班搜索服务之一
2017/11/09 全球购物
什么是View State?
2013/01/27 面试题
最新大学毕业求职简历的自我评价
2013/10/18 职场文书
生产助理岗位职责
2014/06/18 职场文书
大学活动总结模板
2014/07/10 职场文书
教师节活动总结
2014/08/29 职场文书
银行竞聘报告范文
2014/11/06 职场文书
2015年社区计生工作总结
2015/04/21 职场文书
学生会干部任命书
2015/09/21 职场文书
《月光曲》教学反思
2016/02/16 职场文书
pytorch 中autograd.grad()函数的用法说明
2021/05/12 Python