今日看到一篇文章(https://v8.dev/blog/cost-of-javascript-2019 ,其中有一段是如下描述:
大意是JSON.parse定义对象要比对象自变量定义快。
const data = { foo: 42, bar: 1337 }; // ? 这是蜗牛速度
const data = JSON.parse('{"foo":42,"bar":1337}'); // ? 这是飞机速度
感觉甚是奇怪,至少和我们的理解有出入。于是来决定来测试下。
构造对象
修改for循环的值来构造不同的对象大小。然将对象转换成字符串,拷贝使用
var data={};
for(let i=0;i<10000;i++){
data['listItem'+i] = '我是测试对象'
}
JSON.stringify(data)
直接定义
- 1、对象字面量
const start = Date.now();
const data = {};// 拷贝以上的字符串,然后去掉两侧引号
console.log(Date.now() - start)
- 2、JSON.parse转换
const start = Date.now();
const data = JSON.parse(''); // 直接拷贝的字符串,
console.log(Date.now() - start);
以上两种情况,无论如何调整都是发现对象字面量定义要快,且快不少。
setTimeout内定义
- 1、对象字面量
const start = Date.now();
setTimeou(()=>{
const data = {};// 拷贝以上的字符串,然后去掉两侧引号
console.log(Date.now() - start)
});
- 2、JSON.parse定义
const start = Date.now();
setTimeou(()=>{
const data = JSON.parse(''); // 直接拷贝的字符串,
console.log(Date.now() - start)
});
在循环增加到5万次的时候,仍然是对象字面量的速度更快。
然后我跳转成10万次循环的对象,执行结果如下:
对象字面量:130ms
JSON.parse:131ms
我继续增加到12万次循环的对象,执行结果如下:
对象字面量:173ms
JSON.parse: 156ms
两者相差17ms。此时JS文件大小:3.4M
经过以上测试,结合大佬的文章里面描述的懒解析,解释如下:
在JS执行到setTimeout的时候,尽管代码不会立即执行setTimeout的内容,但是执行器还是会懒解析代码,
- 碰到一个对象字面量定义的对象,会增加一次耗费时间解析。
- 碰到是一个JSON…parse的内容,里面是字符串,实际上代码没有执行,所以不会耗费时间解析。
但是我们都知道,JSON.parse相当于执行了一次parse的转换,更加耗时是正常不过,就如同我们第一种情况的测试一样。但是对象字面量懒解析也需要耗费时间,所以当对象更大的时候,那么对象字面量的懒解析耗费更多的时候,就会JSON.parse性能更优了。
那么如何消除字面量懒解析了:
1、对象定义成全局的。
2、变量定义在 PIFE 中
综上所述,其实绝大部分情况下,我们使用对象字面量定义会更优。
当然也给我们开发风格提供了参考意义,比如对象定义在外层比定义在setTimeout等里面要性能好一些。