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 731a7ae

Browse filesBrowse files
legendecasMylesBorins
authored andcommitted
async_hooks: add async local storage propagation benchmarks
Add micro-benchmarks to verify the performance degradation related to the number of active `AsyncLocalStorage`s. With these benchmarks, trying to improve the async context propagation to be an O(1) operation, which is an operation more frequent compared to `asyncLocalStorage.run` and `asyncLocalStorage.getStore`. PR-URL: #46414 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
1 parent 683a1f8 commit 731a7ae
Copy full SHA for 731a7ae

File tree

Expand file treeCollapse file tree

4 files changed

+186
-0
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

4 files changed

+186
-0
lines changed
Open diff view settings
Collapse file
+46Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
const { AsyncLocalStorage, AsyncResource } = require('async_hooks');
4+
5+
/**
6+
* This benchmark verifies the performance of
7+
* `AsyncLocalStorage.getStore()` on propagation through async
8+
* resource scopes.
9+
*
10+
* - AsyncLocalStorage.run()
11+
* - AsyncResource.runInAsyncScope
12+
* - AsyncResource.runInAsyncScope
13+
* ...
14+
* - AsyncResource.runInAsyncScope
15+
* - AsyncLocalStorage.getStore()
16+
*/
17+
const bench = common.createBenchmark(main, {
18+
resourceCount: [10, 100, 1000],
19+
n: [1e4],
20+
});
21+
22+
function runBenchmark(store, n) {
23+
for (let i = 0; i < n; i++) {
24+
store.getStore();
25+
}
26+
}
27+
28+
function runInAsyncScopes(resourceCount, cb, i = 0) {
29+
if (i === resourceCount) {
30+
cb();
31+
} else {
32+
const resource = new AsyncResource('noop');
33+
resource.runInAsyncScope(() => {
34+
runInAsyncScopes(resourceCount, cb, i + 1);
35+
});
36+
}
37+
}
38+
39+
function main({ n, resourceCount }) {
40+
const store = new AsyncLocalStorage();
41+
runInAsyncScopes(resourceCount, () => {
42+
bench.start();
43+
runBenchmark(store, n);
44+
bench.end(n);
45+
});
46+
}
Collapse file
+46Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
const { AsyncLocalStorage } = require('async_hooks');
4+
5+
/**
6+
* This benchmark verifies the performance of
7+
* `AsyncLocalStorage.getStore()` on multiple `AsyncLocalStorage` instances
8+
* nested `AsyncLocalStorage.run()`s.
9+
*
10+
* - AsyncLocalStorage1.run()
11+
* - AsyncLocalStorage2.run()
12+
* ...
13+
* - AsyncLocalStorageN.run()
14+
* - AsyncLocalStorage1.getStore()
15+
*/
16+
const bench = common.createBenchmark(main, {
17+
sotrageCount: [1, 10, 100],
18+
n: [1e4],
19+
});
20+
21+
function runBenchmark(store, n) {
22+
for (let idx = 0; idx < n; idx++) {
23+
store.getStore();
24+
}
25+
}
26+
27+
function runStores(stores, value, cb, idx = 0) {
28+
if (idx === stores.length) {
29+
cb();
30+
} else {
31+
stores[idx].run(value, () => {
32+
runStores(stores, value, cb, idx + 1);
33+
});
34+
}
35+
}
36+
37+
function main({ n, sotrageCount }) {
38+
const stores = new Array(sotrageCount).fill(0).map(() => new AsyncLocalStorage());
39+
const contextValue = {};
40+
41+
runStores(stores, contextValue, () => {
42+
bench.start();
43+
runBenchmark(stores[0], n);
44+
bench.end(n);
45+
});
46+
}
Collapse file
+46Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
const { AsyncLocalStorage, AsyncResource } = require('async_hooks');
4+
5+
/**
6+
* This benchmark verifies the performance degradation of
7+
* async resource propagation on the increasing number of
8+
* active `AsyncLocalStorage`s.
9+
*
10+
* - AsyncLocalStorage.run() * storageCount
11+
* - new AsyncResource()
12+
* - new AsyncResource()
13+
* ...
14+
* - N new Asyncresource()
15+
*/
16+
const bench = common.createBenchmark(main, {
17+
storageCount: [0, 1, 10, 100],
18+
n: [1e3],
19+
});
20+
21+
function runStores(stores, value, cb, idx = 0) {
22+
if (idx === stores.length) {
23+
cb();
24+
} else {
25+
stores[idx].run(value, () => {
26+
runStores(stores, value, cb, idx + 1);
27+
});
28+
}
29+
}
30+
31+
function runBenchmark(n) {
32+
for (let i = 0; i < n; i++) {
33+
new AsyncResource('noop');
34+
}
35+
}
36+
37+
function main({ n, storageCount }) {
38+
const stores = new Array(storageCount).fill(0).map(() => new AsyncLocalStorage());
39+
const contextValue = {};
40+
41+
runStores(stores, contextValue, () => {
42+
bench.start();
43+
runBenchmark(n);
44+
bench.end(n);
45+
});
46+
}
Collapse file
+48Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
const { AsyncLocalStorage } = require('async_hooks');
4+
5+
/**
6+
* This benchmark verifies the performance degradation of
7+
* async resource propagation on the increasing number of
8+
* active `AsyncLocalStorage`s.
9+
*
10+
* - AsyncLocalStorage.run()
11+
* - Promise
12+
* - Promise
13+
* ...
14+
* - Promise
15+
*/
16+
const bench = common.createBenchmark(main, {
17+
storageCount: [0, 1, 10, 100],
18+
n: [1e5],
19+
});
20+
21+
function runStores(stores, value, cb, idx = 0) {
22+
if (idx === stores.length) {
23+
cb();
24+
} else {
25+
stores[idx].run(value, () => {
26+
runStores(stores, value, cb, idx + 1);
27+
});
28+
}
29+
}
30+
31+
async function runBenchmark(n) {
32+
for (let i = 0; i < n; i++) {
33+
// Avoid creating additional ticks.
34+
await undefined;
35+
}
36+
}
37+
38+
function main({ n, storageCount }) {
39+
const stores = new Array(storageCount).fill(0).map(() => new AsyncLocalStorage());
40+
const contextValue = {};
41+
42+
runStores(stores, contextValue, () => {
43+
bench.start();
44+
runBenchmark(n).then(() => {
45+
bench.end(n);
46+
});
47+
});
48+
}

0 commit comments

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