Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 97e32c7

Browse filesBrowse files
watildeaduh95
authored andcommitted
lib: avoid quadratic shift() in startup snapshot callback
PR-URL: #62914 Reviewed-By: Stephen Belanger <admin@stephenbelanger.com> Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br> Reviewed-By: Ilyas Shabi <ilyasshabi94@gmail.com> Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent 3e10365 commit 97e32c7
Copy full SHA for 97e32c7

2 files changed

+67-6Lines changed: 67 additions & 6 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file
+58Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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+
}
Collapse file

‎lib/internal/v8/startup_snapshot.js‎

Copy file name to clipboardExpand all lines: lib/internal/v8/startup_snapshot.js
+9-6Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@ function throwIfBuildingSnapshot(reason) {
3737
const deserializeCallbacks = [];
3838
let deserializeCallbackIsSet = false;
3939
function runDeserializeCallbacks() {
40-
while (deserializeCallbacks.length > 0) {
41-
const { 0: callback, 1: data } = deserializeCallbacks.shift();
40+
for (let i = 0; i < deserializeCallbacks.length; i++) {
41+
const { 0: callback, 1: data } = deserializeCallbacks[i];
4242
callback(data);
4343
}
44+
deserializeCallbacks.length = 0;
4445
}
4546

4647
function addDeserializeCallback(callback, data) {
@@ -60,14 +61,16 @@ function addDeserializeCallback(callback, data) {
6061
const serializeCallbacks = [];
6162
const afterUserSerializeCallbacks = []; // Callbacks to run after user callbacks
6263
function runSerializeCallbacks() {
63-
while (serializeCallbacks.length > 0) {
64-
const { 0: callback, 1: data } = serializeCallbacks.shift();
64+
for (let i = 0; i < serializeCallbacks.length; i++) {
65+
const { 0: callback, 1: data } = serializeCallbacks[i];
6566
callback(data);
6667
}
67-
while (afterUserSerializeCallbacks.length > 0) {
68-
const { 0: callback, 1: data } = afterUserSerializeCallbacks.shift();
68+
serializeCallbacks.length = 0;
69+
for (let i = 0; i < afterUserSerializeCallbacks.length; i++) {
70+
const { 0: callback, 1: data } = afterUserSerializeCallbacks[i];
6971
callback(data);
7072
}
73+
afterUserSerializeCallbacks.length = 0;
7174
}
7275

7376
function addSerializeCallback(callback, data) {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.