詳解關(guān)于JSON.parse()和JSON.stringify()的性能小測試
JSON.parse(JSON.stringify(obj))我們一般用來深拷貝,其過程說白了,就是利用 JSON.stringify 將js對象序列化(JSON字符串),再使用JSON.parse來反序列化(還原)js對象。至于這行代碼為什么能實現(xiàn)深拷貝,以及它有什么局限性等等,不是本文要介紹的。本文要探究的是,這行代碼的執(zhí)行效率如何?如果隨意使用會不會造成一些問題?
先上兩個js性能測試的依賴函數(shù)
/** * 一個簡單的斷言函數(shù) * @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); }
/** * 一個測試套件,定時器是為了多次執(zhí)行減少誤差 * @param fn {Function} 需要多次執(zhí)行的代碼塊(需要測試、比對性能的代碼塊) * @param config {Object} 配置項,maxCount: 執(zhí)行代碼塊的for循環(huán)次數(shù),times: 定時器執(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}次,定時器執(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 }, ];
場景1:模擬真實環(huán)境中圖表數(shù)據(jù)實時更新
數(shù)據(jù)處理函數(shù)
/** * 處理json數(shù)據(jù)的函數(shù)。模擬真實環(huán)境中圖表數(shù)據(jù)實時更新 * @param lastData {Object} 上一次的數(shù)據(jù) * @param res {Array} 當前數(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
跑起來,先讓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é)果:
場景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內(nèi)部沒有執(zhí)行代碼
maxCount=1000
1.使用 JSON.stringify() 判斷一個對象是否為空對象 的結(jié)果:
intervalTest(isEmptyObject1, {maxCount: 1000});
2.使用 Object.keys().length 判斷一個對象是否為空對象 的結(jié)果:
intervalTest(isEmptyObject2, {maxCount: 1000});
maxCount=10000
1.使用 JSON.stringify() 判斷一個對象是否為空對象 的結(jié)果:
2.使用 Object.keys().length 判斷一個對象是否為空對象 的結(jié)果:
maxCount=100000
1.使用 JSON.stringify() 判斷一個對象是否為空對象 的結(jié)果:
2.使用 Object.keys().length 判斷一個對象是否為空對象 的結(jié)果:
關(guān)于JSON.parse()和JSON.stringify()的測試先到此為止,變換參數(shù)、更改執(zhí)行的代碼塊可能會有不同結(jié)果,以上結(jié)果僅供參考。
小結(jié)論:能不用JSON.parse()和JSON.stringify()就不用,采用替代方案且性能更優(yōu)的。PS:特別是需要多次執(zhí)行的代碼塊,特別是這個JSON數(shù)據(jù)比較龐大時
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- JSON.parse處理非標準Json數(shù)據(jù)出錯的解決
- JSON.parse()和JSON.stringify()使用介紹
- 關(guān)于JSON.parse(),JSON.stringify(),jQuery.parseJSON()的用法
- JSON.parseObject和JSON.toJSONString實例詳解
- javascript中JSON.parse()與eval()解析json的區(qū)別
- JS使用JSON.parse(),JSON.stringify()實現(xiàn)對對象的深拷貝功能分析
- JSON中key動態(tài)設(shè)置及JSON.parse和JSON.stringify()的區(qū)別
- 淺談JSON.parse()和JSON.stringify()
- JSON.parse 數(shù)據(jù)不完整的解決方法
相關(guān)文章
BootStrap table刪除指定行的注意事項(筆記整理)
在前端開發(fā)中遇到這樣的問題,對于table指定行的數(shù)據(jù)進行刪除,花了好長時間才解決,今天小編抽時間給大家介紹BootStrap table刪除指定行的注意事項,需要的朋友參考下吧2017-02-02微信小程序 數(shù)據(jù)封裝,參數(shù)傳值等經(jīng)驗分享
這篇文章主要介紹了微信小程序 數(shù)據(jù)封裝,參數(shù)傳值等經(jīng)驗分享的相關(guān)資料,需要的朋友可以參考下2017-01-01JavaScript簡單實現(xiàn)合并兩個Json對象的方法示例
這篇文章主要介紹了JavaScript簡單實現(xiàn)合并兩個Json對象的方法,結(jié)合實例形式分析了json對象的遍歷、添加實現(xiàn)合并的相關(guān)操作技巧,需要的朋友可以參考下2017-10-10常常會用到的截取字符串substr()、substring()、slice()方法詳解
javascript中給我們提供三個截取字符串的方法,分別是:slice(),substring()和substr()。下面我們對這三個函數(shù)進行詳細說明和比較,需要的朋友可以參考下2015-12-12JavaScript canvas實現(xiàn)俄羅斯方塊游戲
這篇文章主要為大家詳細介紹了JavaScript canvas實現(xiàn)俄羅斯方塊游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-07-07JavaScript實現(xiàn)向右伸出的多級網(wǎng)頁菜單效果
這篇文章主要介紹了JavaScript實現(xiàn)向右伸出的多級網(wǎng)頁菜單效果,通過javascript調(diào)用頁面元素屬性的動態(tài)改變實現(xiàn)向右展開菜單效果,具有一定參考借鑒價值,需要的朋友可以參考下2015-08-08javascript數(shù)組去重方法終極總結(jié)
這篇文章主要介紹了javascript數(shù)組去重終極總結(jié),本文列舉了3種javascript數(shù)組去重方法,并分別分析了它們的優(yōu)缺點,需要的朋友可以參考下2014-06-06