详解关于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 相关文章推荐
Script的加载方法小结
Jan 12 Javascript
suggestion开发小结以及对键盘事件的总结(针对中文输入法状态)
Dec 20 Javascript
一个页面元素appendchild追加到另一个页面元素的问题
Jan 27 Javascript
JS验证身份证有效性示例
Oct 11 Javascript
JQuery判断HTML元素是否存在的两种解决方法
Dec 26 Javascript
jQuery实现HTML5 placeholder效果实例
Dec 09 Javascript
Javascript 正则表达式实现为数字添加千位分隔符
Mar 10 Javascript
全面解析Bootstrap排版使用方法(标题)
Nov 30 Javascript
Javascript实现的StopWatch功能示例
Jun 13 Javascript
js解决软键盘遮挡输入框的问题分享
Dec 19 Javascript
基于Vue中使用节流Lodash throttle详解
Oct 30 Javascript
vue+elementUi 实现密码显示/隐藏+小图标变化功能
Jan 18 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
关于zend studio 出现乱码问题的总结
2013/06/23 PHP
百度工程师讲PHP函数的实现原理及性能分析(三)
2015/05/13 PHP
php文件操作相关类实例
2015/06/18 PHP
深入php内核之php in array
2015/11/10 PHP
基于PHP制作验证码
2016/10/12 PHP
来自国外的14个图片放大编辑的jQuery插件整理
2010/10/20 Javascript
javascript tips提示框组件实现代码
2010/11/19 Javascript
Jquery 插件开发笔记整理
2011/01/17 Javascript
图标线性回归斜着移动到指定的位置
2013/08/16 Javascript
JavaScript设置、获取、清除单值和多值cookie的方法
2015/11/17 Javascript
jQuery自定义组件(导入组件)
2016/11/08 Javascript
使用Node.js实现RESTful API的示例
2017/08/01 Javascript
javascript性能优化之分时函数的介绍
2018/03/28 Javascript
在Ubuntu系统下安装使用Python的GUI工具wxPython
2016/02/18 Python
Python中random模块生成随机数详解
2016/03/10 Python
python自定义函数实现一个数的三次方计算方法
2019/01/20 Python
Python-copy()与deepcopy()区别详解
2019/07/12 Python
Django中间件基础用法详解
2019/07/18 Python
Python内置类型性能分析过程实例
2020/01/29 Python
设置jupyter中DataFrame的显示限制方式
2020/04/12 Python
解决python虚拟环境切换无效的问题
2020/04/30 Python
Python QT组件库qtwidgets的使用
2020/11/02 Python
Python中的流程控制详解
2021/02/18 Python
python模块内置属性概念及实例
2021/02/18 Python
recorder.js 基于Html5录音功能的实现
2020/05/26 HTML / CSS
TripAdvisor印尼站:全球领先的旅游网站
2018/03/15 全球购物
澳洲CFL商城:CHEMIST FOR LESS(中文)
2021/02/28 全球购物
static全局变量与普通的全局变量有什么区别
2014/05/27 面试题
岗位职责定义及内容
2013/11/08 职场文书
给同学的道歉信
2014/01/16 职场文书
财务内勤岗位职责
2014/04/17 职场文书
小学生感恩父母演讲稿
2014/08/28 职场文书
网络研修心得体会
2016/01/08 职场文书
大学军训心得体会800字
2016/01/11 职场文书
创业者如何撰写出一份打动投资人的商业计划书?
2019/07/02 职场文书
5种方法告诉你如何使JavaScript 代码库更干净
2021/09/15 Javascript