在gitee上开了个项目做这个测试: https://gitee.com/littleprog/js_efficiency
测试结果
Array add 10M elements 3 times (by push)
time diff: 284
time diff: 363
time diff: 226
Array add 0.1M elements 3 times (by unshift. unshift is really slow, so I use 1% elements of 10M)
time diff: 737
time diff: 703
time diff: 736
Object add 10M elements
time diff: 244
time diff: 294
time diff: 249
Array delete 10000 elements(by splice from beginning)
time diff: 636
Object delete 10000 elements
time diff: 1
Array modify 10M elements 3 times
time diff: 8
time diff: 7
time diff: 8
Objec modify 10 elements 3 times
time diff: 8
time diff: 8
time diff: 7
总结
- 新增: Array用push新增元素和Object效率差不多, 但是用Unshift新增元素效率惨不忍睹, 效率极低, 在增加的数据量为100K时已经接近1秒时间, 而且估计随着array的变大会越来越低. 所以array的内存块是连续的, unshift是内存整体向后移动后再在前面增加元素的.
- 删除: 同样, 如果array用splice删除排序靠前的元素, 效率也是远远低于使用delete删除Object中的元素.
- 修改: 两者的修改不存在区别.
因此, 对于元素数量极多并且需要随机插入数据和删除数据时, Object才是更好的选择. Array有一个Object没有的功能是Array元素是有序的, 而Object元素是无序的. 虽然Object可以将key值设置为序号, 表现为类似Array的顺序, 但是在随机增加和删除后, 这些序号会被打乱. 事实上, Array比Object低效的部分, 恰恰就是在排序上花费了额外的时间, 每次插入和删除一个元素时, 相当于要将其后面的所有元素序号变更. 另外, array还有个特点是支持for of
循环, 也就是本身是一个迭代器iterator
我猜测NoSQL数据库, 包括腾讯小程序的云数据库, 都是用的Object的方式存储不同条的数据的. 其_id
相当于是key
, 这样随机查找增加删除都比较快. 而排序是需要单独的sort命令, 因为object本身是无序的. 并且经常使用某一个属性排序或者查找时, 还需要预先进行升序或降序索引, 否则数据量大了以后速度估计会惨不忍睹.
所以在本地对大数据量操作时, 要提前考虑好是使用array还是object. 如果必须要有顺序或者要使用迭代器的特性, 那么就只能用array了.