详解关于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 相关文章推荐
一实用的实现table排序的Javascript类库
Sep 12 Javascript
解读JavaScript代码 var ie = !-[1,] 最短的IE判定代码
May 28 Javascript
jquery实现简单的拖拽效果实例兼容所有主流浏览器
Jun 21 Javascript
通过javascript获取iframe里的值示例代码
Jun 24 Javascript
fmt:formatDate的输出格式详解
Jan 09 Javascript
动态加载js、css等文件跨iframe实现
Feb 24 Javascript
jQuery中$.each使用详解
Jan 29 Javascript
jQuery解决IE6、7、8不能使用 JSON.stringify 函数的问题
May 31 Javascript
简单实现js页面切换功能
Jan 10 Javascript
AngularJS  自定义指令详解及实例代码
Sep 14 Javascript
详解Vue-cli代理解决跨域问题
Sep 27 Javascript
axios异步提交表单数据的几种方法
Aug 11 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浮点数精度问题汇总
2015/05/13 PHP
PHP代码判断设备是手机还是平板电脑(两种方法)
2015/10/19 PHP
PHP测试成功的邮件发送案例
2015/10/26 PHP
PHP whois查询类定义与用法示例
2019/04/03 PHP
tp5.1 框架数据库常见操作详解【添加、删除、更新、查询】
2020/05/26 PHP
JavaScript 闭包在封装函数时的简单分析
2009/11/28 Javascript
jquery动态加载图片数据练习代码
2011/08/04 Javascript
原生Js页面滚动延迟加载图片实现原理及过程
2013/06/24 Javascript
JavaScript控制图片加载完成后调用回调函数的方法
2015/03/20 Javascript
JavaScript对象属性检查、增加、删除、访问操作实例
2015/07/08 Javascript
整理Javascript事件响应学习笔记
2015/12/02 Javascript
用js读写cookie的简单方法(推荐)
2016/08/08 Javascript
解决option标签selected=&quot;selected&quot;属性失效的问题
2017/11/06 Javascript
解决bootstrap模态框数据缓存的问题方法
2018/08/10 Javascript
vue v-for出来的列表,点击某个li使得当前被点击的li字体变红操作
2020/07/17 Javascript
js 压缩图片的示例(只缩小体积,不更改图片尺寸)
2020/10/21 Javascript
解决vue 使用axios.all()方法发起多个请求控制台报错的问题
2020/11/09 Javascript
Javascript新手入门之字符串拼接与变量的应用
2020/12/03 Javascript
[01:39]2014DOTA2国际邀请赛 Newbee经理CU专访队伍火力全开
2014/07/15 DOTA
在python的WEB框架Flask中使用多个配置文件的解决方法
2014/04/18 Python
在Python中使用正则表达式的方法
2015/08/13 Python
python编程线性回归代码示例
2017/12/07 Python
Python OpenCV处理图像之滤镜和图像运算
2018/07/10 Python
Python子类继承父类构造函数详解
2019/02/19 Python
详解python中的index函数用法
2019/08/06 Python
Python实现决策树并且使用Graphviz可视化的例子
2019/08/09 Python
美国派对用品及装饰品网上商店:Shindigz
2016/07/30 全球购物
方法名是否可以与构造器的名字相同
2012/06/04 面试题
优秀的教师个人的中文求职信
2013/09/21 职场文书
审核会计岗位职责
2013/11/08 职场文书
诉讼财产保全担保书
2014/05/20 职场文书
领导班子四风查摆对照检查材料思想汇报
2014/10/05 职场文书
优秀班主任主要事迹材料
2014/12/16 职场文书
第一节英语课开场白
2015/06/01 职场文书
解决pytorch读取自制数据集出现过的问题
2021/05/31 Python
Java实现二分搜索树的示例代码
2022/03/17 Java/Android