欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-05-29 14:46:54
json.parse(json.stringify(obj))我们一般用来深拷贝,其过程说白了,就是利用 json.stringify 将js对象序列化(json字符串),...

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数据比较庞大时

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