Worker postMessage - Transfers vs. StructuredCloning (v2)

Revision 2 of this benchmark created on


Description

Check if it's more useful to clone an ArrayBuffer and transfer it or just let the StructuredClone do its magic.

Setup

// create a worker with inline script blob
let script = "onmessage = e => postMessage({ id: e.data.id })";
let blob = URL.createObjectURL(new Blob([script]));
let worker = new Worker(blob);

// setup handler to resolve promises
let resolve;
worker.onmessage = e => { if (resolve) { r = resolve; resolve = null; r(); } };

// buffers: zeroes and filled random
let plain = new ArrayBuffer(1024*1024);
let buf = new ArrayBuffer(1024*1024);
for (let i = 0; i < 16; i++) {
  crypto.getRandomValues(new Uint8Array(buf, i*65536, 65536));
}

Teardown

worker.terminate()

Test runner

Ready to run.

Testing in
TestOps/sec
{ buf }
(async () => {
await new Promise(r => {
  resolve = r;
  worker.postMessage({ id: 0, buf });
});
deferred.resolve();
})();
ready
{ buf.slice }
(async () => {
await new Promise(r => {
  resolve = r;
  worker.postMessage({ id: 0, buf: buf.slice() });
});
deferred.resolve();
})();
ready
{ buf.slice } + transfer
(async () => {
let copy = buf.slice();
await new Promise(r => {
  resolve = r;
  worker.postMessage({ id: 0, copy }, [ copy ]);
});
deferred.resolve();
})();
ready
{ buf.slice } + transfer (zeroes)
(async () => {
let copy = plain.slice();
await new Promise(r => {
  resolve = r;
  worker.postMessage({ id: 0, copy }, [ copy ]);
});
deferred.resolve();
})();
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.