Vladmir Klepov
Vladmir Klepov

Reputation: 41

Javascript Typed array vs simple array: performance

What I'm basically trying to do is to map an array of data points into a WebGL vertex buffer (Float32Array) in realtime (working on animated parametric surfaces). I've assumed that representing data points with Float32Arrays (either one Float32Array per component: [xx...x, yy...y] or interleave them: xyxy...xy) should be faster than storing them in an array of points: [[x, y], [x, y],.. [x, y]] since that'd actually be a nested hash and all. However, to my surprise, that leads to a slowdown of about 15% in all the major browsers (not counting array creation time). Here's a little test I've set up:

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');

Is there anything I'm doing wrong?

Upvotes: 3

Views: 1785

Answers (2)

vitaliydev
vitaliydev

Reputation: 480

In V8 variables can have SMI (int31/int32), double and pointer type. So I guess when you operate with floats it should be converted to double type. If you use usual arrays it is converted to doubles already.

Upvotes: 0

Brian Genisio
Brian Genisio

Reputation: 48137

I think your problem is that you are not comparing the same code. In the first example, you have one large array filled with very small arrays. In the second example, you have two very large arrays, and both of them need to be indexed. The profile is different.

If I structure the first example to be more like the second (two large generic arrays), then the Float32Array implementation far outperforms the generic array implementation.

Here is a jsPerf profile to show it.

Upvotes: 1

Related Questions