详解关于JSON.parse()和JSON.stringify()的性能小测试

 更新时间:2019年03月14日 09:18:51   作者:ican   我要评论

这篇文章主要介绍了详解关于JSON.parse()和JSON.stringify()的性能小测试,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

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()) 深拷贝 的结果:

2.不使用JSON序列化,直接修改参数 的结果:

function handleJsonData(lastData, res) {
  // 1. 使用 JSON.parse(JSON.stringify()) 深拷贝
  // let data = JSON.parse(JSON.stringify(lastData));

  // 2. 不使用JSON序列化,直接修改参数
  let data = lastData;
  
  // ...
}

maxCount=1000

intervalTest(jsonTest, {maxCount: 1000});

1.使用 JSON.parse(JSON.stringify()) 深拷贝 的结果:

2.不使用JSON序列化,直接修改参数 的结果:

maxCount=10000

intervalTest(jsonTest, {maxCount: 10000});

1.使用 JSON.parse(JSON.stringify()) 深拷贝 的结果:

2.不使用JSON序列化,直接修改参数 的结果:

场景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});

2.使用 Object.keys().length 判断一个对象是否为空对象 的结果:

intervalTest(isEmptyObject2, {maxCount: 1000});

maxCount=10000

1.使用 JSON.stringify() 判断一个对象是否为空对象 的结果:

2.使用 Object.keys().length 判断一个对象是否为空对象 的结果:

maxCount=100000

1.使用 JSON.stringify() 判断一个对象是否为空对象 的结果:

2.使用 Object.keys().length 判断一个对象是否为空对象 的结果:

关于JSON.parse()和JSON.stringify()的测试先到此为止,变换参数、更改执行的代码块可能会有不同结果,以上结果仅供参考。

小结论:能不用JSON.parse()和JSON.stringify()就不用,采用替代方案且性能更优的。PS:特别是需要多次执行的代码块,特别是这个JSON数据比较庞大时

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • javascript动态添加、修改、删除对象的属性与方法详解

    javascript动态添加、修改、删除对象的属性与方法详解

    本篇文章主要是对javascript动态添加、修改、删除对象的属性与方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-01-01
  • 全面解析JavaScript中的valueOf与toString方法(推荐)

    全面解析JavaScript中的valueOf与toString方法(推荐)

    本文给大家介绍JavaScript中的valueOf与toString方法,valueOf() 方法可返回 Boolean 对象的原始值,toString() 方法可把一个逻辑值转换为字符串,并返回结果。对js中valueof和tostring相关知识感兴趣的朋友一起学习吧
    2016-06-06
  • canvas简单快速的实现知乎登录页背景效果

    canvas简单快速的实现知乎登录页背景效果

    本篇文章主要介绍了canvas简单快速实现知乎登录页背景效果的相关知识,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-05-05
  • JavaScript中的集合及效率

    JavaScript中的集合及效率

    由于 JavaScript 的语言特性,我们可以向通用对象动态添加和删除属性。所以 Object 也可以看成是 JS 的一种特殊的集合。
    2010-01-01
  • 基于js对象,操作属性、方法详解

    基于js对象,操作属性、方法详解

    下面小编就为大家带来一篇基于js对象,操作属性、方法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • Javascript的一种模块模式

    Javascript的一种模块模式

    全局变量是魔鬼。在YUI中,我们仅用两个全局变量:YAHOO和YAHOO_config。YUI的一切都是使用YAHOO对象级的成员或这个成员作用域内的变量。我们建议在你的应用程序也使用类似的规则。
    2010-09-09
  • js 递归和定时器的实例解析

    js 递归和定时器的实例解析

    本文主要介绍了js递归和定时器的相关知识。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • bootstrap中的 form表单属性role=

    bootstrap中的 form表单属性role="form"的作用详解

    这篇文章主要介绍了bootstrap中的 form表单属性role="form"的作用详解,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-01-01
  • javascript如何写热点图

    javascript如何写热点图

    这篇文章主要介绍了javascript如何写热点图,热点图是以点的形式展示,通过补全周边变化颜色也会相应的调整渐变,对热点图感兴趣的朋友可以参考一下
    2015-12-12
  • JS获取下拉框显示值和判断单选按钮的方法

    JS获取下拉框显示值和判断单选按钮的方法

    这篇文章主要介绍了JS获取下拉框显示值和判断单选按钮的方法,实例分析了javascript针对html下拉框及单选按钮的相关操作技巧,需要的朋友可以参考下
    2015-07-07

最新评论