Page MenuHomePhorge

bench_dense.js
No OneTemporary

Size
5 KB
Referenced Files
None
Subscribers
None

bench_dense.js

const now = () => typeof performance !== 'undefined' && performance.now ? performance.now() : Date.now();
function bench(name, fn, iters = 1) {
// warmup
fn();
const t0 = now();
for (let i = 0; i < iters; i++) fn();
const dt = now() - t0;
const per = (dt / iters).toFixed(3);
console.log(`${name}: ${dt.toFixed(2)} ms total, ${per} ms/iter (${iters} iters)`);
}
// -------------------------------------------------------
// 1. Sequential push — O(n) lkp per push makes this O(n²)
// -------------------------------------------------------
function push_n(n) {
const arr = [];
for (let i = 0; i < n; i++) arr.push(i);
return arr;
}
bench('push 1k', () => push_n(1000), 100);
bench('push 5k', () => push_n(5000), 20);
bench('push 10k', () => push_n(10000), 5);
// -------------------------------------------------------
// 2. Index write — arr[i] = v walks property chain
// -------------------------------------------------------
function index_write(n) {
const arr = [];
for (let i = 0; i < n; i++) arr[i] = i;
return arr;
}
bench('index write 1k', () => index_write(1000), 100);
bench('index write 5k', () => index_write(5000), 20);
// -------------------------------------------------------
// 3. Index read — arr[i] walks property chain from head
// -------------------------------------------------------
function index_read(arr, n) {
let sum = 0;
for (let i = 0; i < n; i++) sum += arr[i];
return sum;
}
{
const arr1k = push_n(1000);
bench('index read 1k', () => index_read(arr1k, 1000), 200);
}
{
const arr5k = push_n(5000);
bench('index read 5k', () => index_read(arr5k, 5000), 20);
}
// -------------------------------------------------------
// 4. Random access — worst case for linked property chain
// -------------------------------------------------------
function random_read(arr, indices) {
let sum = 0;
for (let i = 0; i < indices.length; i++) sum += arr[indices[i]];
return sum;
}
{
const n = 2000;
const arr = push_n(n);
const indices = [];
let s = 7;
for (let i = 0; i < n; i++) {
s = (s * 1103515245 + 12345) & 0x7fffffff;
indices.push(s % n);
}
bench('random read 2k', () => random_read(arr, indices), 50);
}
// -------------------------------------------------------
// 5. Pop — must walk chain to find last element
// -------------------------------------------------------
function push_then_pop(n) {
const arr = [];
for (let i = 0; i < n; i++) arr.push(i);
for (let i = 0; i < n; i++) arr.pop();
}
bench('push+pop 1k', () => push_then_pop(1000), 50);
// -------------------------------------------------------
// 6. Iteration — forEach / map / filter / reduce
// -------------------------------------------------------
{
const arr1k = push_n(1000);
bench('forEach 1k', () => {
let s = 0;
arr1k.forEach(x => s += x);
}, 200);
bench('map 1k', () => arr1k.map(x => x * 2), 100);
bench('filter 1k', () => arr1k.filter(x => x % 2 === 0), 100);
bench('reduce 1k', () => arr1k.reduce((a, b) => a + b, 0), 200);
}
// -------------------------------------------------------
// 7. Slice / concat / spread
// -------------------------------------------------------
{
const arr1k = push_n(1000);
bench('slice 1k', () => arr1k.slice(), 100);
bench('concat 1k', () => arr1k.concat(arr1k), 50);
bench('spread 1k', () => [...arr1k], 100);
}
// -------------------------------------------------------
// 8. Sort — reads + writes every element
// -------------------------------------------------------
{
function make_random_arr(n) {
const arr = [];
let s = 42;
for (let i = 0; i < n; i++) {
s = (s * 1103515245 + 12345) & 0x7fffffff;
arr.push(s % 10000);
}
return arr;
}
bench('sort 500', () => make_random_arr(500).sort((a, b) => a - b), 20);
}
// -------------------------------------------------------
// 9. Reverse
// -------------------------------------------------------
{
const arr = push_n(1000);
bench('reverse 1k', () => {
arr.reverse();
}, 100);
}
// -------------------------------------------------------
// 10. Array.from / entries / keys / values
// -------------------------------------------------------
{
const arr = push_n(500);
bench('Array.from 500', () => Array.from(arr), 50);
bench('entries 500', () => arr.entries(), 50);
bench('keys 500', () => arr.keys(), 50);
bench('values 500', () => arr.values(), 50);
}
// -------------------------------------------------------
// 11. JSON.stringify — must iterate all elements
// -------------------------------------------------------
{
const arr = push_n(500);
bench('JSON.stringify 500', () => JSON.stringify(arr), 50);
}
// -------------------------------------------------------
// 12. Scaling test — show O(n²) behavior
// -------------------------------------------------------
console.log('\n--- scaling (push N, expect ~linear with dense) ---');
for (const n of [500, 1000, 2000, 4000]) {
const t0 = now();
push_n(n);
const dt = now() - t0;
console.log(`push ${n}: ${dt.toFixed(2)} ms`);
}
console.log('\n--- scaling (sequential read N, expect ~linear with dense) ---');
for (const n of [500, 1000, 2000, 4000]) {
const arr = push_n(n);
const t0 = now();
index_read(arr, n);
const dt = now() - t0;
console.log(`read ${n}: ${dt.toFixed(2)} ms`);
}

File Metadata

Mime Type
application/javascript
Expires
Thu, Mar 26, 8:10 PM (2 d)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
512077
Default Alt Text
bench_dense.js (5 KB)

Event Timeline