【发布时间】:2017-10-27 22:38:23
【问题描述】:
我基本上想要做的是将一组数据点实时映射到 WebGL 顶点缓冲区 (Float32Array) 中(在动画参数表面上工作)。我假设用 Float32Arrays 表示数据点(每个组件一个 Float32Array:[xx...x,yy...y] 或交错它们:xyxy...xy)应该比将它们存储在数组中更快points: [[x, y], [x, y],.. [x, y]] 因为那实际上是一个嵌套的散列等等。然而,令我惊讶的是,这导致所有主要浏览器的速度降低了约 15%(不包括数组创建时间)。这是我设置的一个小测试:
var points = 250000, iters = 100;
function map_2a(x, y) {return Math.sin(x) + y;}
var output = new Float32Array(3 * points);
// generate data
var data = [];
for (var i = 0; i < points; i++)
data[i] = [Math.random(), Math.random()];
// run
console.time('native');
(function() {
for (var iter = 0; iter < iters; iter++)
for (var i = 0, to = 0; i < points; i++, to += 3) {
output[to] = data[i][0];
output[to + 1] = data[i][1];
output[to + 2] = map_2a(data[i][0], data[i][1]);
}
}());
console.timeEnd('native');
// generate data
var data = [new Float32Array(points), new Float32Array(points)];
for (var i = 0; i < points; i++) {
data[0][i] = Math.random();
data[1][i] = Math.random();
}
// run
console.time('typed');
(function() {
for (var iter = 0; iter < iters; iter++)
for (var i = 0, to = 0; i < points; i++, to += 3) {
output[to] = data[0][i];
output[to + 1] = data[1][i];
output[to + 2] = map_2a(data[0][i], data[1][i]);
}
}());
console.timeEnd('typed');
是不是我做错了什么?
【问题讨论】:
-
这与您的问题无关,但您应该避免在主循环中进行乘法运算。而是在内部循环之前将一个额外的变量初始化为 0,并在每个内部循环块的末尾执行
+= 3。 -
确保将每一个都放在它自己的上下文中,这样变量重新声明就不会引起问题。包装每个测试,将前 3 行排除在外,在
(function() { /* ... test ... */ })()内 -
你没有提到你用什么来对这些进行基准测试。请务必使用console.time,并确保仅包含
// run区域内的代码。没有理由假设 Math.random() 是常数时间。 -
@JosephLennox 是的,我曾经声明了一个特殊的测试函数,并且只将运行部分放入其中,但认为它不相关。感谢console.time,我发明了一辆小自行车来代替它。
标签: javascript arrays performance dynamic-arrays typed-arrays