何时在JavaScript中使用Float32Array而不是Array?

66

在浏览器应用程序中,何时使用Float32Array而不是标准JavaScriptArray才有意义呢?

这个性能测试显示,Float32Array通常要慢一些,如果我理解正确,标准的Array将数字存储为64位,因此在精度上没有优势。

除了任何可能的性能损失之外,Float32Array还有可读性差的缺点——需要使用构造函数:

a = new Float32Array(2);
a[0] = 3.5;
a[1] = 4.5;

使用数组字面量替代

a = [3.5, 4.5];

我问这个问题是因为我正在使用 glMatrix 库,默认使用 Float32Array - 想知道是否有任何理由不强制使用 Array,这将允许我使用数组字面量。


我找不到任何能回答这个问题的网站,我的猜测是主要的好处是它使用更少的内存。因此,如果你正在处理巨大的浮点数数组,这可能是一个好处。 - Barmar
1
可能是将某种语言移植到JavaScript,而Float32Array是最接近源语言所提供的东西。 - Rick Viscomi
2
Typed Array Specification 可能会有所帮助:"该规范提供了与本地二进制数据互操作的API"。 - RobG
1
你仍然可以使用字面量语法:new Float32Array([3.5, 4.5])Float32ArrayFloat64Array 慢得多,因为每次对数组内容进行操作时,值都必须转换为/从 64 位值转换,因此如果内存空间允许且您的目标是速度,请尝试使用 Float64Array - ZachB
3个回答

90
我给glMatrix的开发者发了邮件,以下是他的评论(第2和第3点):
  1. 使用Array比使用Float32Array通常更快创建新对象。对于小数组而言,效果显著,但对于大数组则不太明显(取决于环境)。

  2. TypedArray(例如Float32Array)中**访问**数据通常比从普通数组中访问数据更快,这意味着除了创建新对象之外的大多数数组操作在TypedArrays上更快。

  3. 正如@emidander所述,glMatrix主要是为WebGL开发的,它要求将向量和矩阵作为Float32Array传递。因此,在WebGL应用程序中,从ArrayFloat32Array的潜在昂贵的转换需要包含在任何性能测量中。

因此,最佳选择显然取决于应用程序:
  • 如果数组通常很小,或者对它们的操作很少,以至于构造函数时间占数组寿命的重要比例,请使用Array

  • 如果代码可读性与性能同等重要,请使用Array(即使用[],而不是构造函数)。

  • 如果数组非常大和/或用于多个操作,请使用TypedArray。

  • 对于WebGL应用程序(或其他需要类型转换的应用程序),请使用Float32Array(或其他TypedArray)。


4
“大”和“小”是非常模糊的描述,其含义在不同的语境下会有所变化。当我们谈论Float32Array时,有人能否具体说明什么样的数组被认为是“非常大”的,而什么样的被认为是非常小的?请注意,以下内容仅供参考: - yuvi
12
根据@yuvi的说法,“large”指占用了大量的内存资源。例如,在Node中,我创建了一个包含1千万个数字的数组,整个Node进程占用了86MB的内存。如果使用一个包含1千万个数字的Float32Array,Node只会占用46MB的内存。 - Benjamin

8

0
在当今的浏览器实现中,与原始数组相比,使用Float32Array对可写性和性能都有影响。似乎即使是gl-matrix的作者也认为需要重构该库以消除对Float32Array的依赖:https://github.com/toji/gl-matrix/issues/359

这种性能影响的假设通常是不正确的,而且在你提供的 GitHub 问题中也受到了挑战。简而言之,快速未经优化的(重新)分配在使用类型化数组时表现更差,但是具有内存预分配的适当优化代码在使用类型化数组时表现更好。与“长”常规数组相比,“长”类型化数组(除float64外)的内存影响也较短。 - John Weisz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接