Files
scriptc/benchmarks/runtime/workloads/channel-messages.ts
T
Chris Tate 3d00b5b837 Size encoded messages to their nodes and wake a channel's owner once per batch
A message encoder started its node array at 16 nodes of 184 bytes and
kept the array, with its unused capacity, until the message was
received. A port that queued many messages held about 3 KB of zeroed
memory per message: 200,000 queued numbers took about 590 MB, and the
page faults made postMessage cost about 1.3 µs. The node array now
starts at 4 nodes and is trimmed to the message's node count when
encoding ends.

scr_channel_post posted a wake event, and with it a pipe write and a
condition broadcast, to the receiving thread's mailbox for every
message. The owner's loop counts a port with queued messages as ready,
so only a message that finds the queue empty needs to wake it.

bench/channel-messages, added here, posts 200,000 messages (numbers and
small objects) on a MessageChannel before the port delivers any.
2026-10-19 23:24:56 -05:00

22 lines
813 B
TypeScript

// MessageChannel messages within one thread: the program posts the given
// number of messages, half of them numbers and half small objects, before
// the port delivers any, so all of them are queued at once. Argument: the
// number of messages.
import { MessageChannel } from "node:worker_threads";
const count = Number(process.argv[2] ?? "200000");
const { port1, port2 } = new MessageChannel();
let received = 0;
let sum = 0;
port1.on("message", (value: number | { id: number; name: string }) => {
sum += typeof value === "number" ? value : value.id + value.name.length;
if (++received === count) {
console.log(`${count} messages, sum ${sum}`);
port1.close();
}
});
for (let i = 0; i < count; i++) {
if (i % 2 === 0) port2.postMessage(i);
else port2.postMessage({ id: i, name: "item" });
}