Skip to content

Instantly share code, notes, and snippets.

@postspectacular
Last active October 18, 2022 10:43
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save postspectacular/bea4fdbaa1479cc11a064e453dd7fe17 to your computer and use it in GitHub Desktop.
Save postspectacular/bea4fdbaa1479cc11a064e453dd7fe17 to your computer and use it in GitHub Desktop.
JS ImageData update benchmarks showing perf gains (2-4x) from using u32 memory views over standard u8 accesses
import { suite } from "@thi.ng/bench";
const w = 640;
const h = 480;
const idata = new ImageData(w, h);
// exposed u8clampedarray
const u8 = idata.data;
// rewrap same memory as u32
const u32 = new Uint32Array(u8.buffer);
suite(
[
{
title: "slow (single val)",
fn: () => {
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
u8[y * w + x] = 0x10; // r
u8[y * w + x + 1] = 0x20; // g
u8[y * w + x + 2] = 0x30; // b
u8[y * w + x + 3] = 0x40; // a
}
}
},
},
{
title: "fast (single val)",
fn: () => {
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
// 4x less memory accesses
u32[y * w + x] = 0x40302010; // abgr
}
}
},
},
{
title: "fast (single val bitshift)",
fn: () => {
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
// 4x less memory accesses
u32[y * w + x] =
(0x40 << 24) | (0x30 << 16) | (0x20 << 8) | 0x10; // abgr
}
}
},
},
{
title: "slow (random rgb)",
fn: () => {
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
u8[y * w + x] = Math.random() * 0xff; // r
u8[y * w + x + 1] = Math.random() * 0xff; // g
u8[y * w + x + 2] = Math.random() * 0xff; // b
u8[y * w + x + 3] = 0xff; // a
}
}
},
},
{
title: "fast (random rgb)",
fn: () => {
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
// 4x less memory accesses
u32[y * w + x] =
0xff000000 | (Math.random() * 0xffffff); // abgr
}
}
},
},
{
title: "fast (random rgb bitshift)",
fn: () => {
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
// 4x less memory accesses, abgr
u32[y * w + x] =
0xff000000 |
((Math.random() * 0xff) << 16) |
((Math.random() * 0xff) << 8) |
(Math.random() * 0xff);
}
}
},
},
],
{ size: 4, warmup: 10, iter: 1000 }
);
Title Iter Size Total Mean Median Min Max Q1 Q3 SD%
slow (single val) 1000 4 1513.00 1.51 2.00 1.00 5.00 1.00 2.00 34.08
fast (single val) 1000 4 628.00 0.63 1.00 0.00 1.00 0.00 1.00 76.96
fast (single val bitshif 1000 4 639.00 0.64 1.00 0.00 2.00 0.00 1.00 75.49
slow (random rgb) 1000 4 24885.00 24.88 25.00 24.00 33.00 25.00 25.00 2.78
fast (random rgb) 1000 4 8145.00 8.15 8.00 8.00 9.00 8.00 8.00 4.32
fast (random rgb bitshif 1000 4 22229.00 22.23 22.00 21.00 25.00 22.00 22.00 2.23
benchmarking: slow (single val)
    warmup... 17.00ms (10 runs)
    total: 1485.00ms, runs: 1000 (@ 4 calls/iter)
    mean: 1.48ms, median: 1.00ms, range: [1.00..2.00]
    q1: 1.00ms, q3: 2.00ms
    sd: 33.65%
benchmarking: fast (single val)
    warmup... 8.00ms (10 runs)
    total: 633.00ms, runs: 1000 (@ 4 calls/iter)
    mean: 0.63ms, median: 1.00ms, range: [0.00..1.00]
    q1: 0.00ms, q3: 1.00ms
    sd: 76.14%
benchmarking: fast (single val bitshift)
    warmup... 7.00ms (10 runs)
    total: 627.00ms, runs: 1000 (@ 4 calls/iter)
    mean: 0.63ms, median: 1.00ms, range: [0.00..1.00]
    q1: 0.00ms, q3: 1.00ms
    sd: 77.13%
benchmarking: slow (random rgb)
    warmup... 254.00ms (10 runs)
    total: 24839.00ms, runs: 1000 (@ 4 calls/iter)
    mean: 24.84ms, median: 25.00ms, range: [24.00..35.00]
    q1: 25.00ms, q3: 25.00ms
    sd: 2.42%
benchmarking: fast (random rgb)
    warmup... 84.00ms (10 runs)
    total: 8299.00ms, runs: 1000 (@ 4 calls/iter)
    mean: 8.30ms, median: 8.00ms, range: [8.00..13.00]
    q1: 8.00ms, q3: 9.00ms
    sd: 5.77%
benchmarking: fast (random rgb bitshift)
    warmup... 225.00ms (10 runs)
    total: 21938.00ms, runs: 1000 (@ 4 calls/iter)
    mean: 21.94ms, median: 22.00ms, range: [21.00..30.00]
    q1: 22.00ms, q3: 22.00ms
    sd: 2.73%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment