var N = 1000000
var x = new Float32Array(N);
var y = new Float32Array(N);
var z = new Float32Array(N);
var interlaced = new Float32Array(3*N);
var vectors = [];
for (var i = 0, li=x.length; i < li; ++i) {
x[i] = Math.random();
y[i] = Math.random();
z[i] = Math.random();
vectors.push( {x:Math.random(), y:Math.random(), z:Math.random()} );
}
for (var i = 0, li=interlaced.length; i < li; ++i) {
interlaced[i] = Math.random();
}
var vector;
for (var i = 0, li=vectors.length; i < li; ++i) {
vector = vectors[i];
vector.x = 2 * vector.x;
vector.y = 2 * vector.y;
vector.z = 2 * vector.z;
}
for (var i = 0, li=x.length; i < li; ++i) {
x[i] = 2 * x[i];
y[i] = 2 * y[i];
z[i] = 2 * z[i];
}
for (var i = 0, li=x.length; i < li; ++i) {
x[i] = 2 * x[i];
}
for (var i = 0, li=y.length; i < li; ++i) {
y[i] = 2 * y[i];
}
for (var i = 0, li=z.length; i < li; ++i) {
z[i] = 2 * z[i];
}
for (var i = 0, li=interlaced.length; i < li; ++i) {
interlaced[i] = 2*interlaced[i];
}
for (var i = 0, li=interlaced.length; i < li; i+=3) {
interlaced[i] = 2*interlaced[i];
interlaced[i+1] = 2*interlaced[i+1];
interlaced[i+2] = 2*interlaced[i+2];
}
var vector;
for (var i = 0, li=vectors.length; i < li; ++i) {
vector = vectors[i];
vector['x'] = 2 * vector['x'];
vector['y'] = 2 * vector['y'];
vector['z'] = 2 * vector['z'];
}
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
AoS | |
SoA - one loop | |
SoA - one component per loop | |
Interlaced Array - no loop unrolling | |
Interlaced Array - with loop unrolling | |
AoS (bracket notation) |
Test name | Executions per second |
---|---|
AoS | 97.3 Ops/sec |
SoA - one loop | 32.3 Ops/sec |
SoA - one component per loop | 53.0 Ops/sec |
Interlaced Array - no loop unrolling | 52.5 Ops/sec |
Interlaced Array - with loop unrolling | 53.8 Ops/sec |
AoS (bracket notation) | 94.1 Ops/sec |
I'll provide an explanation of the benchmark and its various aspects.
Benchmark Definition
The benchmark is designed to measure the performance of different approaches for multiplying lists of vectors in JavaScript. The test case creates a list of 1,000,000 random vectors and multiplies each vector by 2 using different methods:
Options Compared
The benchmark compares four variants of AoS and SoA:
Pros and Cons
Latest Benchmark Result
The benchmark result shows the executions per second (FPS) for each test case on a specific device (Firefox 49, Windows 7). The top performer is Interlaced Array - With Loop Unrolling, followed closely by Structured Array (SoA). The AoS variants trail behind, with the "bracket notation" variant performing slightly better than the others.
Conclusion
The benchmark highlights the importance of data structure choice and implementation details in achieving optimal performance. Interlacing arrays can provide a significant performance boost due to improved cache locality, but may require more complex loop unrolling logic. The best approach will depend on specific use cases and requirements.