詳解關(guān)于JSON.parse()和JSON.stringify()的性能小測(cè)試
JSON.parse(JSON.stringify(obj))我們一般用來(lái)深拷貝,其過(guò)程說(shuō)白了,就是利用 JSON.stringify 將js對(duì)象序列化(JSON字符串),再使用JSON.parse來(lái)反序列化(還原)js對(duì)象。至于這行代碼為什么能實(shí)現(xiàn)深拷貝,以及它有什么局限性等等,不是本文要介紹的。本文要探究的是,這行代碼的執(zhí)行效率如何?如果隨意使用會(huì)不會(huì)造成一些問(wèn)題?
先上兩個(gè)js性能測(cè)試的依賴函數(shù)
/**
* 一個(gè)簡(jiǎn)單的斷言函數(shù)
* @param value {Boolean} 斷言條件
* @param desc {String} 一個(gè)消息
*/
function assert(value, desc) {
let li = document.createElement('li');
li.className = value ? 'pass' : 'fail';
li.appendChild(document.createTextNode(desc));
document.getElementById('results').appendChild(li);
}
/**
* 一個(gè)測(cè)試套件,定時(shí)器是為了多次執(zhí)行減少誤差
* @param fn {Function} 需要多次執(zhí)行的代碼塊(需要測(cè)試、比對(duì)性能的代碼塊)
* @param config {Object} 配置項(xiàng),maxCount: 執(zhí)行代碼塊的for循環(huán)次數(shù),times: 定時(shí)器執(zhí)行次數(shù)
*/
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循環(huán):${maxCount}次,定時(shí)器執(zhí)行:${times}次,平均值:${average} ms`;
document.body.appendChild(p);
}
}, 1000);
}
定義一些初始數(shù)據(jù)
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
},
];
場(chǎng)景1:模擬真實(shí)環(huán)境中圖表數(shù)據(jù)實(shí)時(shí)更新
數(shù)據(jù)處理函數(shù)
/**
* 處理json數(shù)據(jù)的函數(shù)。模擬真實(shí)環(huán)境中圖表數(shù)據(jù)實(shí)時(shí)更新
* @param lastData {Object} 上一次的數(shù)據(jù)
* @param res {Array} 當(dāng)前數(shù)據(jù)
* @returns data 處理完成后的結(jié)果集
*/
function handleJsonData(lastData, res) {
// 1. 使用 JSON.parse(JSON.stringify()) 深拷貝
let data = JSON.parse(JSON.stringify(lastData));
// 2. 不使用JSON序列化,直接修改參數(shù)
// 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
跑起來(lái),先讓maxCount=100,for循環(huán)100次
let jsonTest = function () {
jsonData = handleJsonData(jsonData, res);
};
intervalTest(jsonTest, {maxCount: 100});
1.使用 JSON.parse(JSON.stringify()) 深拷貝 的結(jié)果:

2.不使用JSON序列化,直接修改參數(shù) 的結(jié)果:
function handleJsonData(lastData, res) {
// 1. 使用 JSON.parse(JSON.stringify()) 深拷貝
// let data = JSON.parse(JSON.stringify(lastData));
// 2. 不使用JSON序列化,直接修改參數(shù)
let data = lastData;
// ...
}

maxCount=1000
intervalTest(jsonTest, {maxCount: 1000});
1.使用 JSON.parse(JSON.stringify()) 深拷貝 的結(jié)果:

2.不使用JSON序列化,直接修改參數(shù) 的結(jié)果:

maxCount=10000
intervalTest(jsonTest, {maxCount: 10000});
1.使用 JSON.parse(JSON.stringify()) 深拷貝 的結(jié)果:

2.不使用JSON序列化,直接修改參數(shù) 的結(jié)果:

場(chǎng)景2:判斷一個(gè)對(duì)象是否為空對(duì)象
// 1. 使用 JSON.stringify() 判斷一個(gè)對(duì)象是否為空對(duì)象
let isEmptyObject1 = function () {
if (JSON.stringify(jsonData) === '{}') {
// do something
}
};
// 2. 使用 Object.keys().length 判斷一個(gè)對(duì)象是否為空對(duì)象
let isEmptyObject2 = function () {
if (Object.keys(jsonData).length === 0) {
// do something
}
};
只是走了一下判斷條件,if內(nèi)部沒(méi)有執(zhí)行代碼
maxCount=1000
1.使用 JSON.stringify() 判斷一個(gè)對(duì)象是否為空對(duì)象 的結(jié)果:
intervalTest(isEmptyObject1, {maxCount: 1000});

2.使用 Object.keys().length 判斷一個(gè)對(duì)象是否為空對(duì)象 的結(jié)果:
intervalTest(isEmptyObject2, {maxCount: 1000});

maxCount=10000
1.使用 JSON.stringify() 判斷一個(gè)對(duì)象是否為空對(duì)象 的結(jié)果:

2.使用 Object.keys().length 判斷一個(gè)對(duì)象是否為空對(duì)象 的結(jié)果:

maxCount=100000
1.使用 JSON.stringify() 判斷一個(gè)對(duì)象是否為空對(duì)象 的結(jié)果:

2.使用 Object.keys().length 判斷一個(gè)對(duì)象是否為空對(duì)象 的結(jié)果:

關(guān)于JSON.parse()和JSON.stringify()的測(cè)試先到此為止,變換參數(shù)、更改執(zhí)行的代碼塊可能會(huì)有不同結(jié)果,以上結(jié)果僅供參考。
小結(jié)論:能不用JSON.parse()和JSON.stringify()就不用,采用替代方案且性能更優(yōu)的。PS:特別是需要多次執(zhí)行的代碼塊,特別是這個(gè)JSON數(shù)據(jù)比較龐大時(shí)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- JSON.parse處理非標(biāo)準(zhǔn)Json數(shù)據(jù)出錯(cuò)的解決
- JSON.parse()和JSON.stringify()使用介紹
- 關(guān)于JSON.parse(),JSON.stringify(),jQuery.parseJSON()的用法
- JSON.parseObject和JSON.toJSONString實(shí)例詳解
- javascript中JSON.parse()與eval()解析json的區(qū)別
- JS使用JSON.parse(),JSON.stringify()實(shí)現(xiàn)對(duì)對(duì)象的深拷貝功能分析
- JSON中key動(dòng)態(tài)設(shè)置及JSON.parse和JSON.stringify()的區(qū)別
- 淺談JSON.parse()和JSON.stringify()
- JSON.parse 數(shù)據(jù)不完整的解決方法
相關(guān)文章
微信小程序?qū)崿F(xiàn)文章關(guān)注功能詳細(xì)流程
在社交小程序里有個(gè)常見(jiàn)的場(chǎng)景是關(guān)注功能,我們本篇以關(guān)注已經(jīng)發(fā)布的文章為例,講解一下關(guān)注功能如何實(shí)現(xiàn)2022-08-08
Javascript實(shí)現(xiàn)購(gòu)物車功能的詳細(xì)代碼
這篇文章使用js實(shí)現(xiàn)購(gòu)物車的價(jià)格計(jì)算,商品數(shù)量更換,商品刪除等功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
js中int和string數(shù)據(jù)類型互相轉(zhuǎn)化實(shí)例
在本篇文章里小編給大家分享了關(guān)于js中int和string數(shù)據(jù)類型互相轉(zhuǎn)化實(shí)例和代碼,需要的朋友們學(xué)習(xí)下。2019-01-01
微信小程序?qū)崿F(xiàn)答題倒計(jì)時(shí)
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)答題倒計(jì)時(shí),自定義計(jì)時(shí)器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09
通過(guò)javascript設(shè)置css屬性的代碼
通過(guò)javascript設(shè)置css屬性的方法需要的朋友可以參考下。2009-12-12
JS+CSS實(shí)現(xiàn)的漂亮漸變背景特效代碼(6個(gè)漸變效果)
這篇文章主要介紹了JS+CSS實(shí)現(xiàn)的漂亮漸變背景特效代碼,包含6個(gè)漸變效果,涉及JavaScript針對(duì)頁(yè)面元素屬性動(dòng)態(tài)操作的相關(guān)技巧,需要的朋友可以參考下2016-03-03

