用单个值填充 Uint16Array 的最快方法

Fastest way to fill Uint16Array with a single value

var a = Uint16Array(16384), n = a.length, c = 65;
for (var i = 0; i < n; i++) a[i] = c;

有没有办法更快地做到这一点?这是每个单元格两个字节的类型化数组。

我记得 memset() 来自 C 或 fillchar 来自 Pascal。

我建议使用 TypedArrays 的 fill method:

var a = Uint16Array(16384).fill(65);

您必须对它是否真的比循环更快进行基准测试,但它应该由引擎优化(尽管他们可能还没有实现)。

理论上,类型化数组上的新 fill() 方法是一个自然的候选者,因为它会以编译速度在内部填充缓冲区,因此性能更快。

不幸的是,情况并非如此。 This performance test 表明,在撰写本文时,传统的 while 循环要快很多倍。即使这个测试对 while 循环有轻微的惩罚。

另外,fill()目前是only supported in Firefox

因此,仅使用 Uint16Array 且具有最佳跨平台支持的最快方法是:

var i = 0, a = new Uint16Array(16384);
while(i < 16384) a[i++] = 65;

Uint16/32 数组总是内存对齐的,所以在某些情况下它们的长度在四字节边界上匹配,使用 32 位数组而不是 2x16 位值填充(重构随意):

var i = 0, len = 16384, a = new Uint16Array(len), c = 65;
if (len % 4) {
    while(i < len) a[i++] = c;            // fill Uint16Array as-is
}
else {
    var u32 = new Uint32Array(a.buffer),  // shares the same byte-buffer as a
        len32 = u32.length,
        v = (c << 16) | c;                // make value span 2x16 bits
    while(i < len32) u32[i++] = v;        // fill at close to 2x speed
}
// use "a" here