我一直在玩类型化数组 https://developer.mozilla.org/en-US/docs/JavaScript_typed_arrays在 JavaScript 中。
var buffer = new ArrayBuffer(16);
var int32View = new Int32Array(buffer);
我想象普通数组([1, 257, true])
JavaScript 中的性能很差,因为它们的值可以是任何类型,因此,达到内存中的偏移量并不是微不足道的。
我最初认为 JavaScript 数组下标的工作方式与对象相同(因为它们有很多相似之处),并且是hash map http://en.wikipedia.org/wiki/Hash_table基于,需要基于哈希的查找。但我还没有找到太多可信的信息来证实这一点。
因此,我认为类型化数组表现如此出色的原因是它们的工作方式与 C 中的普通数组类似,在 C 语言中它们始终是类型化的。给出上面的初始代码示例,并希望获得类型化数组中的第 10 个值......
var value = int32View[10];
- 类型是
Int32
,所以每个值必须包含32
位或4
bytes.
- 下标是
10
.
- 所以该值在内存中的位置是
<array offset> + (4 * 10)
,然后阅读4
字节来获取总值。
我基本上只是想证实我的假设。我对此的想法是否正确,如果不正确,请详细说明。
我查看了V8源码 https://github.com/v8/v8看看我自己能不能回答这个问题,但是我的C很生疏,而且我对C++也不太熟悉。
出于性能原因,类型化数组是由 WebGL 标准委员会设计的。通常,Javascript 数组是通用的,可以保存对象、其他数组等 - 并且元素在内存中不一定是连续的,就像在 C 中一样。WebGL 要求缓冲区在内存中是连续的,因为这就是底层 C API 所期望的他们。如果不使用类型化数组,则将普通数组传递给 WebGL 函数需要大量工作:必须检查每个元素,检查类型,如果它是正确的(例如浮点数),则将其复制到单独的顺序数组中类似 C 的缓冲区,然后将该顺序缓冲区传递给 C API。哎呀——工作量很大!对于性能敏感的 WebGL 应用程序,这可能会导致帧速率大幅下降。
另一方面,就像您在问题中建议的那样,类型化数组在其幕后存储中使用了类似 C 的连续缓冲区。当您写入类型化数组时,您实际上是在幕后分配给类似 C 的数组。就 WebGL 而言,这意味着相应的 C API 可以直接使用缓冲区。
请注意,您的内存地址计算还不够:浏览器must还对数组进行边界检查,以防止超出范围的访问。任何类型的 Javascript 数组都会发生这种情况,但在许多情况下,聪明的 Javascript 引擎可以在证明索引值已经在范围内时省略检查(例如从 0 循环到数组的长度)。它还必须检查数组索引是否确实是数字而不是字符串或其他内容!但本质上就像您所描述的那样,使用类似 C 的寻址。
BUT...那不是全部!在某些情况下,聪明的 Javascript 引擎可以也推导出普通Javascript数组的类型。在像 V8 这样的引擎中,如果你创建一个普通的 Javascript 数组并且只在其中存储浮点数,V8 可能会乐观地确定它是一个浮点数数组并优化它生成的代码。其性能与类型化数组相当。因此,类型化数组实际上并不是达到最大性能所必需的:只需可预测地使用数组(每个元素都具有相同类型),并且某些引擎也可以对此进行优化。
那么为什么类型化数组仍然需要存在呢?
- 像推导数组类型这样的优化是真的很复杂。如果 V8 推断出一个普通数组中只有浮点数,那么您将一个对象存储在一个元素中,它必须去优化并重新生成使数组再次通用的代码。所有这一切都透明地进行,这是一项相当大的成就。类型化数组要简单得多:它们保证是一种类型,并且您不能在其中存储其他内容(例如对象)。
- 优化永远不会保证发生;您可以在普通数组中仅存储浮点数,但引擎可能会出于各种原因决定不对其进行优化。
- 事实上它们要简单得多,这意味着其他不太复杂的 JavaScript 引擎可以轻松实现它们。他们不需要所有高级的去优化支持。
- 即使使用真正先进的引擎,证明可以使用优化也是极其困难的,有时甚至是不可能的。类型化数组显着简化了引擎需要能够围绕它进行优化的证明级别。从类型化数组返回的值肯定是某种类型,引擎可以针对该类型的结果进行优化。从普通数组返回的值理论上可以具有任何类型,并且引擎可能无法证明它总是具有相同类型的结果,因此生成效率较低的代码。因此,围绕类型化数组的代码更容易优化。
- 类型化数组消除了犯错误的机会。您不可能意外地存储一个对象并突然获得更差的性能。
因此,简而言之,普通数组理论上可以与类型数组一样快。但类型化数组可以更轻松地达到峰值性能。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)