Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
Buffer Access 4
(version: 0)
Comparing performance of:
DataView AoS vs DataView byte-aligned AoS vs TypedArray byte-aligned AoS vs TypeArray SoA
Created:
4 years ago
by:
Guest
Jump to the latest result
Script Preparation code:
var bench1buffer; var bench2buffer; var bench3buffer; var size = 1_000_000; { const stride = 10; bench1buffer = new ArrayBuffer(stride * size); /* 0 u16 id 2 f32 x 6 f32 y */ for (let i = 0; i < size; i++) { const struct = new DataView(bench1buffer, i * stride, stride); struct.setUint16(0, i, true); struct.setFloat32(2, i, true); struct.setFloat32(6, i * 2, true); } } { const stride = 12; bench2buffer = new ArrayBuffer(stride * size); /* 0 u16 id 4 f32 x 8 f32 y */ for (let i = 0; i < size; i++) { const struct = new DataView(bench2buffer, i * stride, stride); struct.setUint16(0, i, true); struct.setFloat32(4, i, true); struct.setFloat32(8, i * 2, true); } } { bench3buffer = { id: new Uint16Array(size), x: new Float32Array(size), y: new Float32Array(size), }; for (let i = 0; i < size; i++) { bench3buffer.id[i] = i; bench3buffer.x[i] = i; bench3buffer.y[i] = i * 2; } }
Tests:
DataView AoS
const stride = 10; /* 0 u16 id 2 f32 x 6 f32 y */ const view = new DataView(bench1buffer); let sum = 0; for (let i = 0; i < size; i++) { const offset = i * stride; const id = view.getUint16(offset, true); const x = view.getFloat32(offset + 2, true); const y = view.getFloat32(offset + 6, true); sum += id + x * y; } console.log(1, sum);
DataView byte-aligned AoS
const stride = 12; /* 0 u16 id 4 f32 x 8 f32 y */ const view = new DataView(bench2buffer); let sum = 0; for (let i = 0; i < size; i++) { const offset = i * stride; const id = view.getUint16(offset, true); const x = view.getFloat32(offset + 4, true); const y = view.getFloat32(offset + 8, true); sum += id + x * y; } console.log(2, sum);
TypedArray byte-aligned AoS
const stride = 12; /* 0 u16 id 4 f32 x 8 f32 y */ const f32s = new Float32Array(bench2buffer); const u16s = new Uint16Array(bench2buffer); let sum = 0; for (let i = 0; i < size; i++) { const offset = i * stride; const id = u16s[offset / 2]; const x = f32s[offset / 4 + 1]; const y = f32s[offset / 4 + 2]; sum += id + x * y; } console.log(3, sum);
TypeArray SoA
let sum = 0; const ids = bench3buffer.id; const xs = bench3buffer.x; const ys = bench3buffer.y; for (let i = 0; i < size; i++) { const id = ids[i]; const x = xs[i]; const y = ys[i]; sum += id + x * y; } console.log(4, sum);
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (4)
Previous results
Fork
Test case name
Result
DataView AoS
DataView byte-aligned AoS
TypedArray byte-aligned AoS
TypeArray SoA
Fastest:
N/A
Slowest:
N/A
Latest run results:
No previous run results
This benchmark does not have any results yet. Be the first one
to run it!
Autogenerated LLM Summary
(model
llama3.2:3b
, generated one year ago):
I'll break down what's being tested, the options compared, and the pros and cons of each approach. **What is being tested?** The benchmark tests the performance of three different approaches for accessing data in an array: 1. **DataView Array-of-Structures (AoS)**: This approach uses `DataView` to access individual elements in a buffer as if it were a structured array. 2. **DataView Byte-aligned AoS**: Similar to the first approach, but with a byte alignment between the struct members. 3. **TypedArray Array-of-Structures (SoA)**: This approach uses typed arrays (`Uint16Array`, `Float32Array`) to access individual elements in a buffer as if it were a structured array. **Options compared** The benchmark compares the performance of these three approaches: * `DataView AoS` and `DataView Byte-aligned AoS`: These two approaches differ only in how they align the struct members in memory. * `TypedArray SoA`: This approach uses typed arrays, which can provide better performance due to their optimized access patterns. **Pros and cons of each approach** Here's a brief summary: ### DataView Array-of-Structures (AoS) Pros: * Simple and easy to implement * Works well for small to medium-sized data structures Cons: * May incur more overhead due to the `DataView` object creating a new buffer view * Alignment issues can lead to poor performance if not handled correctly ### DataView Byte-aligned AoS Pros: * Aligns struct members by default, reducing alignment-related issues * Similar performance profile to `DataView AoS` Cons: * May still incur some overhead due to the `DataView` object creating a new buffer view * Alignment can be tricky to manage, especially for complex data structures ### TypedArray Array-of-Structures (SoA) Pros: * Optimized access patterns and caching * Can provide better performance, especially for large datasets * Simplifies code by using familiar typed array APIs Cons: * More complex implementation compared to `DataView` approaches * Limited control over memory alignment **Why did the latest benchmark result favor TypedArray SoA?** The results indicate that `TypedArray SoA` is currently the fastest approach, likely due to its optimized access patterns and caching. However, it's essential to note that the performance difference between these approaches can be small, and other factors like memory alignment and data structure complexity may still impact performance. In conclusion, while all three approaches have their pros and cons, `TypedArray SoA` appears to offer a good balance of performance, simplicity, and control. However, further investigation into specific use cases and requirements is necessary to determine the best approach for a particular application.
Related benchmarks:
Buffer Access
Buffer Access 2
Buffer Access 2 - const arrays
Buffer Access 3
Comments
Confirm delete:
Do you really want to delete benchmark?