繁体   English   中英

如何针对V8中的访问时间优化少量对象引用?

[英]How can I optimize a smallish array of object references for access time in V8?

我正在开发一款游戏,因此必须考虑小的性能提升以及大的性能提升。

我正在阅读V8中的数组初始化,特别是本文建议使用格式var myArray = new Array(100)最终比var myArray = []对于小数组更快(作者建议少于~1000个元素作为小门槛)。

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

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

 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速度,可以改善上述初始化吗?

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

预分配和元素种类跟踪彼此独立。 当你知道你需要的大小时,继续分配一个具有该容量的阵列,无论你要在那里存储什么样的东西。

也就是说,如果你从一个空数组开始并随着它去增长它,那也很好。 严格地说,该策略对于增长步骤有一些额外的成本,并且稍后访问元素时会有一些好处,因为引擎知道所有元素都存在。 但在绝大多数情况下,总体差异太小而无关紧要,你应该做你觉得最可读/最方便的事情。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM