当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 详解关于JSON.parse()和JSON.stringify()的性能小测试

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

2019年05月28日  | 移动技术网IT编程  | 我要评论

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

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网