详解关于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 Hack
Jul 24 Javascript
javascript学习笔记(十) js对象 继承
Jun 19 Javascript
Jquery Post处理后不进入回调的原因及解决方法
Jul 15 Javascript
node.js微信公众平台开发教程
Mar 04 Javascript
在JSP中如何实现MD5加密的方法
Nov 02 Javascript
半个小时学json(json传递示例)
Dec 25 Javascript
微信小程序 Toast自定义实例详解
Jan 20 Javascript
JS传参及动态修改页面布局
Apr 13 Javascript
JS匿名函数和匿名自执行函数概念与用法分析
Mar 16 Javascript
vue实现文件上传读取及下载功能
Nov 17 Javascript
Jquery滑动门/tab切换实现方法完整示例
Jun 05 jQuery
微信小程序基于高德地图API实现天气组件(动态效果)
Oct 22 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中echo()和print()、require()和include()等易混淆函数的区别
2012/02/22 PHP
解析php 版获取重定向后的地址(代码)
2013/06/26 PHP
JQuery上传插件Uploadify使用详解及错误处理
2010/04/27 Javascript
在JS中最常看到切最容易迷惑的语法(转)
2010/10/29 Javascript
JS动态显示表格上下frame的方法
2015/03/31 Javascript
js剪切板应用clipboardData实例解析
2016/05/29 Javascript
整理一些最近经常遇到的前端面试题
2017/04/25 Javascript
jquery实现图片放大点击切换
2017/06/06 jQuery
Vue2.0 axios前后端登陆拦截器(实例讲解)
2017/10/27 Javascript
关于vue的语法规则检测报错问题的解决
2018/05/21 Javascript
vue上传图片到oss的方法示例(图片带有删除功能)
2018/09/27 Javascript
一步一步实现Vue的响应式(对象观测)
2019/09/02 Javascript
JS绘图Flot应用图形绘制异常解决方案
2020/10/16 Javascript
[02:36]DOTA2亚洲邀请赛小组赛精彩集锦:EE凭借法力虚空拿下4杀
2017/03/30 DOTA
[05:20]2018DOTA2亚洲邀请赛主赛事第三日战况回顾 LGD率先挺进胜者组决赛
2018/04/06 DOTA
python批量替换页眉页脚实例代码
2018/01/22 Python
高效使用Python字典的清单
2018/04/04 Python
通过python顺序修改文件名字的方法
2018/07/11 Python
python实现顺序表的简单代码
2018/09/28 Python
使用Python实现文字转语音并生成wav文件的例子
2019/08/08 Python
Django如何实现网站注册用户邮箱验证功能
2019/08/14 Python
Python通过两个dataframe用for循环求笛卡尔积
2020/04/29 Python
python中def是做什么的
2020/06/10 Python
python打开音乐文件的实例方法
2020/07/21 Python
Python绘制词云图之可视化神器pyecharts的方法
2021/02/23 Python
css3实现二维码扫描特效的示例
2020/10/29 HTML / CSS
Html+Css+Jquery实现左侧滑动拉伸导航菜单栏的示例代码
2020/03/17 HTML / CSS
HEMA法国:荷兰原创设计
2019/02/21 全球购物
亚洲领先的设计购物网站:Pinkoi
2020/11/26 全球购物
信息服务专业毕业生求职信
2014/03/02 职场文书
单位法定代表人授权委托书
2014/09/20 职场文书
2015年学校教务处工作总结
2015/05/11 职场文书
新学期家长寄语2016
2015/12/03 职场文书
利用Pycharm连接服务器的全过程记录
2021/07/01 Python
「女孩的钓鱼慢活」全新版权绘公布
2022/03/21 日漫
小程序实现侧滑删除功能
2022/06/25 Javascript