我建议大家关注一件事情,那就是node.js最近成为了Chrome V8的一等公民,因此我建议学习V8,不仅可以了解它如何处理这些实现细节,还可以了解其原因。
首先,本文应该对读者有益,因为它专注于编写优化的同构JavaScript代码:
https://blog.sessionstack.com/how-javascript-works-inside-the-v8-engine-5-tips-on-how-to-write-optimized-code-ac089e62b12e
上面的文章详细介绍了JIT(即时编译器)是如何工作的,因此您应该能够在阅读后得出确切的问题。
以下是摘录:
阵列:避免稀疏数组,其中键不是增量数字。没有每个元素的稀疏数组是哈希表。访问这种数组中的元素更加昂贵。此外,尽量避免预分配大型数组。最好随着进展而增长。最后,不要删除数组中的元素。它使密钥稀疏。
其次,我还建议先阅读此内容,然后再从V8的角度出发:
http://www.jayconrod.com/posts/52/a-tour-of-v8-object-representation
第三点,作为关键的附加事实,我一段时间前读了这个答案,现在时不时地会回想起来。我非常惊讶我现在才发现它。我字面上谷歌搜索了“stack overflow optimize train tracks”并找到了它。感谢 Google:
为什么处理排序数组比处理未排序数组快?
是的,那个答案确实有27,000个赞。
那篇文章谈到了分支预测,我希望你意识到这一点,因为它可能对你处理数据的方式产生一些影响,不仅仅是数组。再次注意我链接的第一篇文章,并注意它描述对象键的顺序时所说的内容。
通过理解实现细节并理解为什么问题被以那种方式解决,可以优化性能。
最后,除了标量值(我们称之为原始值 - String、Number、Boolean等),JavaScript 中的所有东西都是对象。
以下是一个引人思考的例子:
const arr = ['one', 'two', 'three']
const sameArr = {
0: 'one',
1: 'two',
2: 'three',
}
我们可以像处理对象一样解构数组:
const yolo = ['one', 'two', 'three']
const {
0: one,
1: two,
2: three,
} = yolo
console.log('Pretty cool:', one, two, three)
你可以从这个例子中得到一些提示,了解为什么改变键的顺序可能会对底层哈希表造成破坏。仅仅因为你看不到键并不意味着它们不存在或者不受影响。
在上面的例子中,如果它是一个映射,你可以使用
sameArr.get('0')
来获取数值表中确切的位置。
我还建议小心阅读旧版JavaScript材料,因为ES6进行了大量重构。我觉得更适合引导您的是V8材料。
ArrayBuffer
旨在成为连续的内存块,这是为了性能考虑而精确设计的。 - Máté Safranka