【问题标题】:How can I optimize a smallish array of object references for access time in V8?如何优化 V8 中访问时间的小对象引用数组?
【发布时间】:2018-09-16 00:45:09
【问题描述】:

我正在开发一款游戏,因此必须同时考虑性能提升小和大。

我正在阅读 V8 中的数组初始化,特别是 this article,这表明对于小型数组,使用 var myArray = new Array(100) 格式最终比 var myArray = [] 更快(作者建议将小于 ~1000 个元素作为小型数组的阈值)。

鉴于一些假设,不难看出原因。特别是,如果优化后数组的元素都是相同类型的,比如说,所有整数,它们应该被预先分配在连续的内存中,并且不会导致 V8 改变它对数组as described here 的内部表示。当元素在别处使用时,这也将允许编译器对形状做出假设。

然而,在我的情况下,我需要一个对象引用数组,并且我能够按顺序对它们进行初始化。所以,继续我们从上面所知道的,我想出了这个:

class A {
    constructor() {
        this.particles = new Array(60);
        for (var i = 0; i < particles.length; ++i) {
            this.particles[i] = new Particle();
        }
    }
}
class Particle {
    //...
}

正如第一篇文章所述,这是他处理数字类型的最快方法。因此,我假设 V8 假定每个数组的一种本机数字类型的大小并为其分配空间。但是,我不确定是哪个。我也不确定对象引用的大小与分配每个元素的本机类型的大小相比如何。

一个较小的问题是,如果默认元素大小分配大于它需要的一个数组,该数组只包含对一个对象的引用(所有相同类型,并且所有假定在内存中都是连续的),是使用这种数组初始化策略每个元素浪费的空间?有没有办法避免这种情况?如果是这样,是否可以保留访问速度的优化?

优化每个Particle的访问速度,上面的初始化可以改进吗?

【问题讨论】:

    标签: javascript arrays optimization ecmascript-6 v8


    【解决方案1】:

    V8 开发人员在这里。 TL;DR:你做的很好。

    预分配和元素种类跟踪是相互独立的。当您知道您将需要的大小时,请继续分配具有该容量的数组,无论您要在其中存储什么样的东西。

    也就是说,如果您从一个空数组开始并在执行过程中对其进行扩展,那也很好。严格来说,该策略对增长步骤有一些额外的成本,并且在稍后访问元素时有一些好处,因为引擎知道所有元素都存在。但在绝大多数情况下,总体差异太小了,你应该只做你认为最易读/最方便的事情。

    关于您对元素大小的疑惑:在 64 位平台上,所有内容都具有相同的大小(即 64 位 ;-))。在 32 位平台上,指针是 32 位的,而双精度仍然是 64 位,但 V8 不会为更大的元素预先分配空间然后浪费它,所以你不必担心。

    关于您的来源:我发现很难理解那篇文章的建议,所以我倾向于忽略它。特别是,最后出现的“技巧”(var a = []; a.length = N; 而不是var a = new Array(N);)根本没有任何意义,并且给定的“解释”在这种情况下不适用。 V8 在引擎盖下有效地做了同样的事情,所以你认为你可以测量的任何差异都几乎可以保证是随机噪声。谨防微基准,因为它们通常具有误导性!

    【讨论】:

    • 我真的很想知道为什么你没有在 holeydense 旁边制作第三种数组,比如 growth ,这将密集到某个索引,但具有(预分配的)更大的length。当它已满时,您可以将其转换为稠密,否则将其视为有孔。
    • 很有趣,谢谢。所以出于好奇,在 32 位平台上,如果使用 new Array() 预分配一个数组,你如何决定是为双精度数(64 位)还是指针(32 位)调整元素的大小?
    • Joseph:默认情况下,V8 会预先分配指针大小的元素(严格来说,“小整数”大小,但这些元素被定义为具有指针大小的表示)并在以下情况下将数组转换为双精度元素需要,但是还有一个相当复杂的机制可以让数组创建站点“了解”数组将用于什么,因此可以在一段时间后预分配正确的元素类型。
    • Bergi:dense/packed 数组的意义在于避免额外的检查。如果 V8 必须做一个“这个索引在密集部分吗?”检查,这将抵消大多数可能的好处,而不是简单地holey。此外,packedholey 之间的差异通常很小,因此在该区域投入更多的复杂性是不值得的。
    猜你喜欢
    • 1970-01-01
    • 2023-04-07
    • 2011-07-15
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 1970-01-01
    相关资源
    最近更新 更多