用单个值填充 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
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