◐ Shell
clean mode source ↗

lib: avoid quadratic shift() in startup snapshot callback · nodejs/node@97e32c7

1+

'use strict';

2+3+

// Benchmarks startup time when deserialize callbacks are registered in a

4+

// startup snapshot, measuring real binary execution with --snapshot-blob.

5+6+

const common = require('../common.js');

7+

const { spawnSync } = require('child_process');

8+

const { mkdtempSync, writeFileSync, rmSync } = require('fs');

9+

const { tmpdir } = require('os');

10+

const path = require('path');

11+12+

const bench = common.createBenchmark(main, {

13+

count: [10, 100, 1000, 10000],

14+

n: [30],

15+

});

16+17+

function buildSnapshot(snapshotBlob, fixtureScript, count) {

18+

writeFileSync(fixtureScript, `

19+

'use strict';

20+

const v8 = require('node:v8');

21+

for (let i = 0; i < ${count}; i++) {

22+

v8.startupSnapshot.addDeserializeCallback(() => {});

23+

}

24+

v8.startupSnapshot.setDeserializeMainFunction(() => {});

25+

`);

26+

const result = spawnSync(process.execPath, [

27+

'--snapshot-blob', snapshotBlob,

28+

'--build-snapshot', fixtureScript,

29+

]);

30+

if (result.status !== 0) {

31+

throw new Error(`Failed to build snapshot:\n${result.stderr}`);

32+

}

33+

}

34+35+

function main({ n, count }) {

36+

const dir = mkdtempSync(path.join(tmpdir(), 'node-bench-snapshot-'));

37+

const snapshotBlob = path.join(dir, 'snapshot.blob');

38+

const fixtureScript = path.join(dir, 'build.js');

39+40+

try {

41+

buildSnapshot(snapshotBlob, fixtureScript, count);

42+43+

const warmup = 3;

44+

let finished = -warmup;

45+46+

while (finished < n) {

47+

const child = spawnSync(process.execPath, ['--snapshot-blob', snapshotBlob]);

48+

if (child.status !== 0) {

49+

throw new Error(`Snapshot run failed:\n${child.stderr}`);

50+

}

51+

finished++;

52+

if (finished === 0) bench.start();

53+

if (finished === n) bench.end(n);

54+

}

55+

} finally {

56+

rmSync(dir, { recursive: true, force: true });

57+

}

58+

}