Skip to content

Commit 97ad72f

Browse files
legendecasdanielleadams
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 3aef68d commit 97ad72f

4 files changed

+186
-0
lines changed
Lines 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+
}
Lines 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+
}
Lines 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+
}
Lines 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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy