数组的快速模式&字典模式
3 views
3 views
看下这个问题,哪段代码效率更高:
```js
const arr1 = []
for (let i = 0; i < 10000000; ++i) {
arr1[i] = 0
}
```
```js
const arr2 = []
arr2[10000000 - 1] = 1
for (let i = 0; i < 10000000; ++i) {
arr2[i] = 0
}
```
答案是:左边效率更高,利用了数组的`快速模式`
我们可以测试一下:
```js
console.time("a")
const arr1 = []
for (let i = 0; i < 10000000; ++i) {
arr1[i] = 0
}
console.timeEnd("a")
console.time("b")
const arr2 = []
arr2[10000000 - 1] = 1
for (let i = 0; i < 10000000; ++i) {
arr2[i] = 0
}
console.timeEnd("b")
```
得到打印结果:
```bash
a: 116.369ms
b: 1.008s
```
为什么?
1. V8 内部有多种方式存放 JS 数组
2. 数组从 0 到 length - 1 无空洞,会进入`快速模式`,存放为 array。
3. 数组中间有空洞,会进入`字典模式`,存放为`HashMap`。
> 这是 V8 一个优化策略,保证用最合适的数据结构处理当下场景,如果遇到数据量过大或者是松散结构,就改变为 HashMap,牺牲遍历性能,换取访问性能。
带来的启示:
1. 从 0 开始初始化数组,避免数组进入字典模式。
2. 让数组保持紧凑,比main数组进入字典模式。