'use strict';
window.N = 1000000;
class PointAndVelocity {
constructor(x, y, vx, vy) {
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
}
}
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
class Velocity {
constructor(vx, vy) {
this.vx = vx;
this.vy = vy;
}
}
aos = Array(N).fill(new PointAndVelocity(0, 0, 0, 0))
.map(() => new PointAndVelocity(Math.random() * 100|0, Math.random() * 100|0, Math.random() * 100|0, Math.random() * 100|0));
// SoA, we try to duplicate the data so numeric differences are out of the question.
points = Array(N).fill(new Point(0, 0)).
.map((_, i) => new Point(aos[i].x, aos[i].y));
velocities = Array(N).fill(new Velocity(0, 0)).
.map((_, i) => new Velocity(aos[i].vx, aos[i].vy));
var N = window.N;
for (var i = 0; i < N; ++i) {
var point = points[i];
var velocity = velocities[i];
point.x += velocity.vx;
point.y += velocity.vy;
}
var N = window.N;
for (var i = 0; i < N; ++i) {
var pav = aos[i]
pav.x += pav.vx;
pav.y += pav.vy;
}
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
SoA | |
AoS |
Test name | Executions per second |
---|---|
SoA | 3521552.0 Ops/sec |
AoS | 3509384.0 Ops/sec |
This benchmark compares two data organization strategies in JavaScript: Structure of Arrays (SoA) and Array of Structures (AoS), in the context of object-oriented programming (OOP) using classes. The benchmark demonstrates how each approach performs when manipulating point and velocity data.
Data Structures:
The benchmark creates two different data setups:
aos
) is created where each element is an instance of the PointAndVelocity
class. Manipulations happen on these objects directly.points
and velocities
) are created for position and velocity data, respectively.Test cases:
points
and velocities
arrays. Each point's position is updated based on its corresponding velocity, allowing performance comparisons of separate arrays for organizing eigenvalues.aos
array, updating the position of each point using velocity stored in the same object.Pros:
Cons:
Pros:
Cons:
points
array correctly corresponds to the element in the velocities
array).The benchmark results show that both approaches yield quite similar performance, with SoA slightly outperforming AoS. This may indicate that for this size of data (1,000,000 points), the benefits of caching in SoA can provide a slight performance advantage, despite the overhead from managing multiple arrays.
In summary, this benchmark illustrates the performance trade-offs between SoA and AoS patterns when implementing object-oriented designs. Developers may choose SoA for scenarios involving numerical computations on large datasets to leverage cache-friendly memory access patterns. In contrast, AoS may be preferred for smaller datasets or when data coherence and ease of use are prioritized over raw performance.
This benchmark serves as a useful reference for software engineers in understanding the implications of their data structures on performance at scale.