详解关于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 相关文章推荐
动态添加option及createElement使用示例
Jan 26 Javascript
jQuery.position()方法获取不到值的安全替换方法
Mar 13 Javascript
web打印小结
Jan 11 Javascript
使用jQuery ajaxupload插件实现无刷新上传文件
Apr 23 jQuery
js实现点击切换checkbox背景图片的简单实例
May 08 Javascript
javascript帧动画(实例讲解)
Sep 02 Javascript
vue获取dom元素注意事项
Dec 28 Javascript
Webpack path与publicPath的区别详解
May 03 Javascript
解决angular2 获取到的数据无法实时更新的问题
Aug 31 Javascript
ES6 新增的创建数组的方法(小结)
Aug 01 Javascript
vue+vant实现商品列表批量倒计时功能
Jan 13 Javascript
在vue项目中封装echarts的步骤
Dec 25 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
帖几个PHP的无限分类实现想法~
2007/01/02 PHP
PHP中strtr字符串替换用法详解
2014/11/26 PHP
PHP中Session和Cookie是如何操作的
2015/10/10 PHP
php与python实现的线程池多线程爬虫功能示例
2016/10/12 PHP
javascript  Error 对象 错误处理
2008/05/18 Javascript
Javascript 日期对象Date扩展方法
2009/05/30 Javascript
jquery事件机制扩展插件 jquery鼠标右键事件
2011/12/21 Javascript
table对象中的insertRow与deleteRow使用示例
2014/01/26 Javascript
一些老手都不一定知道的JavaScript技巧
2014/05/06 Javascript
输入法的回车与消息发送快捷键回车的冲突解决方法
2016/08/09 Javascript
jQuery常见的选择器及用法介绍
2016/12/20 Javascript
JS如何判断浏览器类型和详细区分IE各版本浏览器
2017/03/04 Javascript
css和js实现弹出登录居中界面完整代码
2017/11/26 Javascript
Javascript防止图片拉伸的自适应处理方法
2017/12/26 Javascript
Material(包括Material Icon)在Angular2中的使用详解
2018/02/11 Javascript
Vue+webpack项目基础配置教程
2018/02/12 Javascript
vue使用技巧及vue项目中遇到的问题
2018/06/04 Javascript
webpack-mvc 传统多页面组件化开发详解
2019/05/07 Javascript
CentOS中使用virtualenv搭建python3环境
2015/06/08 Python
python 队列详解及实例代码
2016/10/18 Python
Python 搭建Web站点之Web服务器网关接口
2016/11/06 Python
Python实现读写INI配置文件的方法示例
2018/06/09 Python
深入理解Django自定义信号(signals)
2018/10/15 Python
PyCharm 2019.3发布增加了新功能一览
2019/12/08 Python
python多进程下的生产者和消费者模型
2020/05/07 Python
Python如何转换字符串大小写
2020/06/04 Python
HTML5 WebSocket实现点对点聊天的示例代码
2018/01/31 HTML / CSS
波兰家居饰品和厨房配件网上商店:Maleomi
2020/12/15 全球购物
地下停车场租赁协议范本
2014/10/07 职场文书
幼儿园感谢信
2015/01/21 职场文书
幼儿园安全教育月活动总结
2015/05/08 职场文书
2015年大学辅导员工作总结
2015/05/12 职场文书
初一数学教学反思
2016/02/17 职场文书
python自动计算图像数据集的RGB均值
2021/06/18 Python
React如何创建组件
2021/06/27 Javascript
nginx共享内存的机制详解
2022/03/21 Servers