详解关于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 自定义事件初探
Aug 21 Javascript
jQuery中用dom操作替代正则表达式
Dec 29 Javascript
JS的框架Polymer中的dom-if和is属性使用说明
Jul 29 Javascript
基于BootStarp的Dailog
Apr 28 Javascript
AngularJs解决跨域问题案例详解(简单方法)
May 19 Javascript
JavaScript中利用构造器函数模拟类的方法
Feb 16 Javascript
Vue.extend构造器的详解
Jul 17 Javascript
js实现扫雷小程序的示例代码
Sep 27 Javascript
vue缓存的keepalive页面刷新数据的方法
Apr 23 Javascript
vue 全局环境切换问题
Oct 27 Javascript
jQuery实现html可联动的百分比进度条
Mar 26 jQuery
JS数组Reduce方法功能与用法实例详解
Apr 29 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函数
2011/05/31 PHP
PHP中读写文件实现代码
2011/10/20 PHP
php导出excel格式数据问题
2014/03/11 PHP
php读取目录所有文件信息dir示例
2014/03/18 PHP
js中parseFloat(参数1,参数2)定义和用法及注意事项
2013/01/27 Javascript
jQuery自定义事件的简单实现代码
2014/01/27 Javascript
JavaScript 基本概念
2015/01/20 Javascript
jQuery使用animate创建动画用法实例
2015/08/07 Javascript
jquery基础知识第一讲之认识jquery
2016/03/17 Javascript
第二章之Bootstrap 页面排版样式
2016/04/25 Javascript
JS与jQuery实现隔行变色的方法
2016/09/09 Javascript
详解JS-- 浮点数运算处理
2016/11/28 Javascript
根据Bootstrap Paginator改写的js分页插件
2016/12/25 Javascript
Javascript 链式作用域详细介绍
2017/02/23 Javascript
JavaScript实现前端实时搜索功能
2020/03/26 Javascript
微信小程序如何修改本地缓存key中单个数据的详解
2019/04/26 Javascript
JS中的算法与数据结构之常见排序(Sort)算法详解
2019/08/16 Javascript
通过实例解析JavaScript for in及for of区别
2020/06/15 Javascript
Python生成器(Generator)详解
2015/04/13 Python
Python标准库defaultdict模块使用示例
2015/04/28 Python
Python datetime和unix时间戳之间相互转换的讲解
2019/04/01 Python
python中多个装饰器的调用顺序详解
2019/07/16 Python
Django中Middleware中的函数详解
2019/07/18 Python
django中的图片验证码功能
2019/09/18 Python
Python使用shutil模块实现文件拷贝
2020/07/31 Python
HTML5本地存储和本地数据库实例详解
2017/09/05 HTML / CSS
原装进口全世界:天猫国际
2016/08/03 全球购物
实习护理工作自我评价
2013/09/25 职场文书
给国外客户的邀请函
2014/01/30 职场文书
服务理念口号
2014/06/11 职场文书
企业总经理助理岗位职责
2014/09/12 职场文书
学校运动会感想
2015/08/10 职场文书
小学生大队委竞选稿
2015/11/20 职场文书
详解Python中的进程和线程
2021/06/23 Python
mysql事务对效率的影响分析总结
2021/10/24 MySQL
MySQL主从切换的超详细步骤
2022/06/28 MySQL