<script>
(async () => {
const importObject = { imports: { } };
const ex = 'https://unpkg.com/@wass80/wasm-queue@0.2.2/wasm_queue_bg.wasm';
const wasm_obj = await WebAssembly.instantiateStreaming(fetch(ex), importObject);
const wasm = wasm_obj.instance.exports;
window.wasm_zigzag = wasm.zigzag
})();
</script>
window.zigzag = (n, init, shift, push)=>{
let seed = 12345;
let size = 0;
let last = -1;
for (let i = 0; i < n; i++) {
if (size > 0 && (seed & 20480) == 0) { // 2^12+2^14=20480
last = shift(init);
size--;
} else {
push(init,seed);
size++;
}
seed = (seed * 1664525 + 1013904223) & 2147483647;
}
if (last !== 1508974062) alert("Assertion Failed!");
}
// 2 Stack
window.stack_shift = x=>{
if (x[0].length == 0){
x[0] = x[1];
x[1] = [];
x[0].reverse();
}
return x[0].pop();
}
window.stack_push = (x,v)=>{
x[1].push(v);
}
// Ring Buffer
window.ring_shift = (a) => {
const res = a.data[a.head];
a.head = (a.head + 1) % a.data.length;
return res;
}
window.ring_push = (a,v)=>{
a.data[a.tail] = v;
a.tail = (a.tail + 1) % a.data.length;
}
window.ring_init = (r) => {return {data: new Array(r), head:0, tail: 0}};
window.int32array_init = (r) => {return {data: new Int32Array(r), head:0, tail: 0}};
window.n = 100000;
zigzag(n, [], a=>a.shift(), (a,v)=>a.push(v))
zigzag(n, [[],[]], stack_shift, stack_push)
zigzag(n, ring_init(n), ring_shift, ring_push)
zigzag(n, int32array_init(n), ring_shift, ring_push)
last = window.wasm_zigzag(n);
if (last !== 1508974062) alert("Assertion Failed!");
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
Array | |
Queue with 2 Stacks | |
Ring Buffer | |
Ring Buffer (Int32Array) | |
(FYI) Rust + wasm |
Test name | Executions per second |
---|---|
Array | 5.1 Ops/sec |
Queue with 2 Stacks | 232.0 Ops/sec |
Ring Buffer | 310.9 Ops/sec |
Ring Buffer (Int32Array) | 416.9 Ops/sec |
(FYI) Rust + wasm | 1590.5 Ops/sec |
Measuring performance is essential in software development, and MeasureThat.net provides a valuable tool for doing so.
Benchmark Overview
The provided benchmark is designed to test the performance of different data structures (Queues) implemented using two stacks. The goal is to compare the execution speed of these different approaches.
Data Structures Compared
There are four data structures compared:
stack_push
function is used to add elements to the queue, while the stack_shift
function is used to remove elements from the front of the queue.ring_shift
function is used to remove elements from the front of the queue, while the ring_push
function is used to add elements to the end of the queue.Int32Array
. It's similar to the previous implementation but uses an array of 32-bit integers instead of JavaScript objects.Options Compared
The options compared are:
stack_push
vs. ring_push
: These functions are used to add elements to the queue.stack_shift
vs. ring_shift
: These functions are used to remove elements from the front of the queue.Pros and Cons
Here's a summary of the pros and cons of each approach:
Performance Results
The provided results show that the ring buffer implementation outperforms the queue with two stacks approach. The native Rust + WebAssembly implementation is also relatively fast, but it serves as a baseline for comparison.
In summary, this benchmark provides valuable insights into the performance characteristics of different data structures implemented using JavaScript. By comparing these approaches, developers can choose the best approach for their specific use case and optimize their code accordingly.