gpt4 book ai didi

javascript - JavaScript 中类型化数组的优点是它们在 C 中的工作方式相同还是相似?

转载 作者:IT王子 更新时间:2023-10-28 23:29:19 26 4
gpt4 key购买 nike

我一直在玩 Typed Arrays在 JavaScript 中。

var buffer = new ArrayBuffer(16);
var int32View = new Int32Array(buffer);

我想普通数组(JavaScript 中的 [1, 257, true]) 性能很差,因为它们的值可以是任何类型,因此,在内存中达到偏移量并非易事。

我最初认为 JavaScript 数组下标的工作方式与对象相同(因为它们有很多相似之处),并且是 hash map基于,需要基于哈希的查找。但我还没有找到太多可信的信息来证实这一点。

因此,我认为 Typed Arrays 表现如此出色的原因是因为它们像 C 中的普通数组一样工作,它们总是被键入。鉴于上面的初始代码示例,并希望获得类型化数组中的第 10 个值...
var value = int32View[10];
  • 类型是 Int32 ,所以每个值必须包含 32位或 4字节。
  • 下标为10 .
  • 所以该值在内存中的位置是 <array offset> + (4 * 10) ,然后阅读 4字节以获取总值。

  • 我基本上只是想确认我的假设。我对此的想法是否正确,如果不正确,请详细说明。

    我查看了 V8 source看看我是否可以自己回答,但我的 C 很生疏,而且我对 C++ 不太熟悉。

    最佳答案

    出于性能原因,类型数组由 WebGL 标准委员会设计。通常 Javascript 数组是通用的,可以保存对象、其他数组等等——并且元素在内存中不一定是顺序的,就像它们在 C 中一样。 WebGL 要求缓冲区在内存中是顺序的,因为这是底层 C API 所期望的他们。如果不使用类型化数组,将普通数组传递给 WebGL 函数需要大量工作:必须检查每个元素,检查类型,如果它是正确的(例如浮点数),则将其复制到单独的序列中类似 C 的缓冲区,然后将该顺序缓冲区传递给 C API。哎哟 - 很多工作!对于性能敏感的 WebGL 应用程序,这可能会导致帧率大幅下降。

    另一方面,正如您在问题中所建议的那样,类型化数组使用已经在其幕后存储中的类似 C 的顺序缓冲区。当您写入类型化数组时,您确实在幕后分配了一个类似 C 的数组。就 WebGL 而言,这意味着缓冲区可以由相应的 C API 直接使用。

    请注意,您的内存地址计算还不够:浏览器 必须还对数组进行边界检查,以防止超出范围的访问。这必须发生在任何类型的 Javascript 数组中,但在许多情况下,聪明的 Javascript 引擎可以在证明索引值已经在边界内时省略检查(例如从 0 循环到数组的长度)。它还必须检查数组索引是否真的是数字而不是字符串或其他东西!但它本质上就像你描述的那样,使用类 C 寻址。

    但是... 那不是全部!在某些情况下,聪明的 Javascript 引擎可以 还推导出普通Javascript数组的类型 .在像 V8 这样的引擎中,如果你创建一个普通的 Javascript 数组并且只在其中存储浮点数,V8 可能会乐观地决定它是一个浮点数数组并优化它为此生成的代码。性能可以等同于类型化数组。所以类型化数组实际上并不是达到最高性能所必需的:只需可预测地使用数组(每个元素都具有相同的类型),一些引擎也可以为此进行优化。

    那么为什么类型化数组仍然需要存在呢?

  • 推导数组类型之类的优化非常复杂。如果 V8 推导出一个普通数组只有浮点数,那么你将一个对象存储在一个元素中,它必须去优化并重新生成代码,使数组再次通用。所有这些都透明地运作,这是一项了不起的成就。类型化数组要简单得多:它们保证是一种类型,并且您不能在其中存储其他东西,例如对象。
  • 优化永远不能保证发生;您可以只将浮点数存储在普通数组中,但引擎可能会出于各种原因决定不对其进行优化。
  • 它们更简单的事实意味着其他不太复杂的 javascript 引擎可以轻松实现它们。他们不需要所有高级去优化支持。
  • 即使使用非常先进的引擎,证明可以使用优化也非常困难,有时甚至是不可能的。类型化数组显着简化了引擎需要能够围绕它进行优化的证明级别。从类型化数组返回的值肯定是某种类型,引擎可以针对该类型的结果进行优化。从普通数组返回的值理论上可以具有任何类型,并且引擎可能无法证明它始终具​​有相同的类型结果,因此生成的代码效率较低。因此,围绕类型化数组的代码更容易优化。
  • 类型化数组消除了犯错的机会。你不能不小心存储一个对象,然后突然变得更糟糕的性能。

  • 所以,简而言之,普通数组理论上可以和类型化数组一样快。但是类型化数组可以更容易地达到峰值性能。

    关于javascript - JavaScript 中类型化数组的优点是它们在 C 中的工作方式相同还是相似?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13328658/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com