| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 7bb6dab commit a77a200
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,39 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + const common = require('../common.js'); | ||
| 3 | + const { execFile } = require('child_process'); | ||
| 4 | + | ||
| 5 | + // Isolates stdout accumulation + maxBuffer handling in execFile(). The child | ||
| 6 | + // writes `chunks` blocks of 64 KiB; the parent accumulates them through the | ||
| 7 | + // native pipe read path and the JS buffering in lib/child_process.js until the | ||
| 8 | + // process exits and the result buffer is handed to the callback. | ||
| 9 | + | ||
| 10 | + const bench = common.createBenchmark(main, { | ||
| 11 | + // Number of 64 KiB blocks written by the child: 1 MiB, 16 MiB, 64 MiB. | ||
| 12 | + chunks: [16, 256, 1024], | ||
| 13 | + n: [10], | ||
| 14 | + }); | ||
| 15 | + | ||
| 16 | + function main({ n, chunks }) { | ||
| 17 | + const script = | ||
| 18 | + 'const b = Buffer.alloc(65536, 0x61);' + | ||
| 19 | + `for (let i = 0; i < ${chunks}; i++) process.stdout.write(b);`; | ||
| 20 | + const args = ['-e', script]; | ||
| 21 | + const options = { | ||
| 22 | + maxBuffer: chunks * 65536 + 65536, | ||
| 23 | + encoding: 'buffer', | ||
| 24 | + }; | ||
| 25 | + | ||
| 26 | + let left = n; | ||
| 27 | + const run = () => { | ||
| 28 | + execFile(process.execPath, args, options, (err) => { | ||
| 29 | + if (err) | ||
| 30 | + throw err; | ||
| 31 | + if (--left === 0) | ||
| 32 | + return bench.end(n); | ||
| 33 | + run(); | ||
| 34 | + }); | ||
| 35 | + }; | ||
| 36 | + | ||
| 37 | + bench.start(); | ||
| 38 | + run(); | ||
| 39 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,47 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + if (process.argv[2] === 'child') { | ||
| 3 | + // Echo every message straight back to the parent. | ||
| 4 | + process.on('message', (msg) => { | ||
| 5 | + process.send(msg); | ||
| 6 | + }); | ||
| 7 | + } else { | ||
| 8 | + const common = require('../common.js'); | ||
| 9 | + const bench = common.createBenchmark(main, { | ||
| 10 | + len: [64, 256, 1024, 4096, 16384, 65536], | ||
| 11 | + serialization: ['json', 'advanced'], | ||
| 12 | + dur: [5], | ||
| 13 | + }); | ||
| 14 | + const { spawn } = require('child_process'); | ||
| 15 | + | ||
| 16 | + function main({ dur, len, serialization }) { | ||
| 17 | + const msg = { payload: '.'.repeat(len) }; | ||
| 18 | + const options = { | ||
| 19 | + stdio: ['ignore', 'ignore', 'ignore', 'ipc'], | ||
| 20 | + serialization, | ||
| 21 | + }; | ||
| 22 | + const child = spawn(process.argv[0], | ||
| 23 | + [process.argv[1], 'child'], options); | ||
| 24 | + | ||
| 25 | + let messages = 0; | ||
| 26 | + let finished = false; | ||
| 27 | + | ||
| 28 | + child.on('message', () => { | ||
| 29 | + messages++; | ||
| 30 | + // Keep one round-trip in flight per completed one so both the serialize | ||
| 31 | + // (write) and deserialize (read) paths stay saturated on both ends. | ||
| 32 | + if (!finished) | ||
| 33 | + child.send(msg); | ||
| 34 | + }); | ||
| 35 | + | ||
| 36 | + bench.start(); | ||
| 37 | + // Prime a window of in-flight messages so the IPC channel never drains. | ||
| 38 | + for (let i = 0; i < 256; i++) | ||
| 39 | + child.send(msg); | ||
| 40 | + | ||
| 41 | + setTimeout(() => { | ||
| 42 | + finished = true; | ||
| 43 | + bench.end(messages); | ||
| 44 | + child.kill(); | ||
| 45 | + }, dur * 1000); | ||
| 46 | + } | ||
| 47 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,43 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + const common = require('../common.js'); | ||
| 3 | + const { spawn } = require('child_process'); | ||
| 4 | + | ||
| 5 | + // Isolates the cost of marshaling spawn() options across the JS -> C++ boundary | ||
| 6 | + // (ProcessWrap::Spawn). A trivial, fast-exiting child is spawned repeatedly | ||
| 7 | + // while scaling the number of environment pairs and arguments that have to be | ||
| 8 | + // converted, so the per-spawn option-handling overhead is the dominant cost. | ||
| 9 | + | ||
| 10 | + const isWindows = process.platform === 'win32'; | ||
| 11 | + const command = isWindows ? 'cmd' : 'true'; | ||
| 12 | + const baseArgs = isWindows ? ['/d', '/s', '/c', 'exit'] : []; | ||
| 13 | + | ||
| 14 | + const bench = common.createBenchmark(main, { | ||
| 15 | + n: [1000], | ||
| 16 | + envc: [0, 64, 256, 1024], | ||
| 17 | + argc: [0, 8, 64], | ||
| 18 | + }); | ||
| 19 | + | ||
| 20 | + function main({ n, envc, argc }) { | ||
| 21 | + const env = { ...process.env }; | ||
| 22 | + for (let i = 0; i < envc; i++) | ||
| 23 | + env[`NODE_BENCH_VAR_${i}`] = `value_${i}`; | ||
| 24 | + | ||
| 25 | + const args = baseArgs.slice(); | ||
| 26 | + for (let i = 0; i < argc; i++) | ||
| 27 | + args.push(`arg_${i}`); | ||
| 28 | + | ||
| 29 | + const options = { env, stdio: ['ignore', 'ignore', 'ignore'] }; | ||
| 30 | + | ||
| 31 | + let left = n; | ||
| 32 | + const go = () => { | ||
| 33 | + if (--left < 0) | ||
| 34 | + return bench.end(n); | ||
| 35 | + const child = spawn(command, args, options); | ||
| 36 | + // The exit code is intentionally ignored: the child only exercises the | ||
| 37 | + // option-marshaling path, it is not expected to do any useful work. | ||
| 38 | + child.on('exit', go); | ||
| 39 | + }; | ||
| 40 | + | ||
| 41 | + bench.start(); | ||
| 42 | + go(); | ||
| 43 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments