详解关于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 相关文章推荐
学习YUI.Ext 第二天
Mar 10 Javascript
JS验证邮箱格式是否正确的代码
Dec 05 Javascript
javascript实现的网站访问量统计代码
Dec 20 Javascript
深入php面向对象、模式与实践
Feb 16 Javascript
原生js实现旋转木马轮播图效果
Feb 27 Javascript
关于在mongoose中填充外键的方法详解
Aug 14 Javascript
解读vue生成的文件目录结构及说明
Nov 27 Javascript
微信小程序使用toast消息对话框提示用户忘记输入用户名或密码功能【附源码下载】
Dec 09 Javascript
vue项目在安卓低版本机显示空白的原因分析(两种)
Sep 04 Javascript
vue+iview 兼容IE11浏览器的实现方法
Jan 07 Javascript
Vue js 的生命周期(看了就懂)(推荐)
Mar 29 Javascript
如何解决vue在ios微信&quot;复制链接&quot;功能问题
Mar 26 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/10/09 PHP
写一个用户在线显示的程序
2006/10/09 PHP
PHP直接修改表内容DataGrid功能实现代码
2015/09/24 PHP
基于PHP制作验证码
2016/10/12 PHP
php 比较获取两个数组相同和不同元素的例子(交集和差集)
2019/10/18 PHP
jQuery 美元符冲突的解决方法
2010/03/28 Javascript
showModalDialog模态对话框的使用详解以及浏览器兼容
2014/01/11 Javascript
struts2+jquery组合验证注册用户是否存在
2014/04/30 Javascript
javascript中Array数组的迭代方法实例分析
2015/02/04 Javascript
JS实现文字向下滚动完整实例
2015/02/06 Javascript
JQuery实现列表中复选框全选反选功能封装(推荐)
2016/11/24 Javascript
jQuery常见面试题之DOM操作详析
2017/07/05 jQuery
了解javascript中的Dom操作
2019/05/27 Javascript
layer实现弹出层自动调节位置
2019/09/05 Javascript
微信小程序自定义弹出模态框禁止底部滚动功能
2020/03/09 Javascript
vue实现自定义多选按钮
2020/07/16 Javascript
JS实现炫酷雪花飘落效果
2020/08/19 Javascript
微信小程序实现简单的select下拉框
2020/11/23 Javascript
JavaScript实现浏览器网页自动滚动并点击的示例代码
2020/12/05 Javascript
python使用cookielib库示例分享
2014/03/03 Python
用python记录运行pid,并在需要时kill掉它们的实例
2017/01/16 Python
用Django实现一个可运行的区块链应用
2018/03/08 Python
pytorch中tensor的合并与截取方法
2018/07/26 Python
使用Python函数进行模块化的实现
2019/11/15 Python
Python操作PostgreSql数据库的方法(基本的增删改查)
2020/12/29 Python
html5新增的属性和废除的属性简要概述
2013/02/20 HTML / CSS
应用化学专业本科生求职信
2013/09/29 职场文书
数控技术专业推荐信
2013/11/01 职场文书
家庭教育先进个人事迹材料
2014/01/24 职场文书
本科毕业生专业自荐书范文
2014/02/05 职场文书
社区母亲节活动总结
2015/02/10 职场文书
社区宣传标语口号
2015/12/26 职场文书
践行三严三实心得体会(2016推荐篇)
2016/01/06 职场文书
2016个人先进事迹材料范文
2016/03/01 职场文书
Python实现socket库网络通信套接字
2021/06/04 Python
Linux安装apache服务器的配置过程
2021/11/27 Servers