summaryrefslogtreecommitdiff
path: root/benchmark
diff options
context:
space:
mode:
authorChengzhong Wu <chengzhong.wcz@alibaba-inc.com>2023-02-04 05:12:17 +0800
committerGitHub <noreply@github.com>2023-02-03 21:12:17 +0000
commit3000d770179029094f7a80ac0a0c95f6a00a01c3 (patch)
tree954531919cef513467bb18a08174b08d8b43d7cb /benchmark
parent88d71dc301028735decf6f12cc1174f13c5cacff (diff)
downloadnode-new-3000d770179029094f7a80ac0a0c95f6a00a01c3.tar.gz
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: https://github.com/nodejs/node/pull/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>
Diffstat (limited to 'benchmark')
-rw-r--r--benchmark/async_hooks/async-local-storage-getstore-nested-resources.js46
-rw-r--r--benchmark/async_hooks/async-local-storage-getstore-nested-run.js46
-rw-r--r--benchmark/async_hooks/async-local-storage-propagate-asyncresource.js46
-rw-r--r--benchmark/async_hooks/async-local-storage-propagate-promise.js48
4 files changed, 186 insertions, 0 deletions
diff --git a/benchmark/async_hooks/async-local-storage-getstore-nested-resources.js b/benchmark/async_hooks/async-local-storage-getstore-nested-resources.js
new file mode 100644
index 0000000000..05b43af627
--- /dev/null
+++ b/benchmark/async_hooks/async-local-storage-getstore-nested-resources.js
@@ -0,0 +1,46 @@
+'use strict';
+const common = require('../common.js');
+const { AsyncLocalStorage, AsyncResource } = require('async_hooks');
+
+/**
+ * This benchmark verifies the performance of
+ * `AsyncLocalStorage.getStore()` on propagation through async
+ * resource scopes.
+ *
+ * - AsyncLocalStorage.run()
+ * - AsyncResource.runInAsyncScope
+ * - AsyncResource.runInAsyncScope
+ * ...
+ * - AsyncResource.runInAsyncScope
+ * - AsyncLocalStorage.getStore()
+ */
+const bench = common.createBenchmark(main, {
+ resourceCount: [10, 100, 1000],
+ n: [1e4],
+});
+
+function runBenchmark(store, n) {
+ for (let i = 0; i < n; i++) {
+ store.getStore();
+ }
+}
+
+function runInAsyncScopes(resourceCount, cb, i = 0) {
+ if (i === resourceCount) {
+ cb();
+ } else {
+ const resource = new AsyncResource('noop');
+ resource.runInAsyncScope(() => {
+ runInAsyncScopes(resourceCount, cb, i + 1);
+ });
+ }
+}
+
+function main({ n, resourceCount }) {
+ const store = new AsyncLocalStorage();
+ runInAsyncScopes(resourceCount, () => {
+ bench.start();
+ runBenchmark(store, n);
+ bench.end(n);
+ });
+}
diff --git a/benchmark/async_hooks/async-local-storage-getstore-nested-run.js b/benchmark/async_hooks/async-local-storage-getstore-nested-run.js
new file mode 100644
index 0000000000..5f8948f62e
--- /dev/null
+++ b/benchmark/async_hooks/async-local-storage-getstore-nested-run.js
@@ -0,0 +1,46 @@
+'use strict';
+const common = require('../common.js');
+const { AsyncLocalStorage } = require('async_hooks');
+
+/**
+ * This benchmark verifies the performance of
+ * `AsyncLocalStorage.getStore()` on multiple `AsyncLocalStorage` instances
+ * nested `AsyncLocalStorage.run()`s.
+ *
+ * - AsyncLocalStorage1.run()
+ * - AsyncLocalStorage2.run()
+ * ...
+ * - AsyncLocalStorageN.run()
+ * - AsyncLocalStorage1.getStore()
+ */
+const bench = common.createBenchmark(main, {
+ sotrageCount: [1, 10, 100],
+ n: [1e4],
+});
+
+function runBenchmark(store, n) {
+ for (let idx = 0; idx < n; idx++) {
+ store.getStore();
+ }
+}
+
+function runStores(stores, value, cb, idx = 0) {
+ if (idx === stores.length) {
+ cb();
+ } else {
+ stores[idx].run(value, () => {
+ runStores(stores, value, cb, idx + 1);
+ });
+ }
+}
+
+function main({ n, sotrageCount }) {
+ const stores = new Array(sotrageCount).fill(0).map(() => new AsyncLocalStorage());
+ const contextValue = {};
+
+ runStores(stores, contextValue, () => {
+ bench.start();
+ runBenchmark(stores[0], n);
+ bench.end(n);
+ });
+}
diff --git a/benchmark/async_hooks/async-local-storage-propagate-asyncresource.js b/benchmark/async_hooks/async-local-storage-propagate-asyncresource.js
new file mode 100644
index 0000000000..e5523452af
--- /dev/null
+++ b/benchmark/async_hooks/async-local-storage-propagate-asyncresource.js
@@ -0,0 +1,46 @@
+'use strict';
+const common = require('../common.js');
+const { AsyncLocalStorage, AsyncResource } = require('async_hooks');
+
+/**
+ * This benchmark verifies the performance degradation of
+ * async resource propagation on the increasing number of
+ * active `AsyncLocalStorage`s.
+ *
+ * - AsyncLocalStorage.run() * storageCount
+ * - new AsyncResource()
+ * - new AsyncResource()
+ * ...
+ * - N new Asyncresource()
+ */
+const bench = common.createBenchmark(main, {
+ storageCount: [0, 1, 10, 100],
+ n: [1e3],
+});
+
+function runStores(stores, value, cb, idx = 0) {
+ if (idx === stores.length) {
+ cb();
+ } else {
+ stores[idx].run(value, () => {
+ runStores(stores, value, cb, idx + 1);
+ });
+ }
+}
+
+function runBenchmark(n) {
+ for (let i = 0; i < n; i++) {
+ new AsyncResource('noop');
+ }
+}
+
+function main({ n, storageCount }) {
+ const stores = new Array(storageCount).fill(0).map(() => new AsyncLocalStorage());
+ const contextValue = {};
+
+ runStores(stores, contextValue, () => {
+ bench.start();
+ runBenchmark(n);
+ bench.end(n);
+ });
+}
diff --git a/benchmark/async_hooks/async-local-storage-propagate-promise.js b/benchmark/async_hooks/async-local-storage-propagate-promise.js
new file mode 100644
index 0000000000..8d6241d076
--- /dev/null
+++ b/benchmark/async_hooks/async-local-storage-propagate-promise.js
@@ -0,0 +1,48 @@
+'use strict';
+const common = require('../common.js');
+const { AsyncLocalStorage } = require('async_hooks');
+
+/**
+ * This benchmark verifies the performance degradation of
+ * async resource propagation on the increasing number of
+ * active `AsyncLocalStorage`s.
+ *
+ * - AsyncLocalStorage.run()
+ * - Promise
+ * - Promise
+ * ...
+ * - Promise
+ */
+const bench = common.createBenchmark(main, {
+ storageCount: [0, 1, 10, 100],
+ n: [1e5],
+});
+
+function runStores(stores, value, cb, idx = 0) {
+ if (idx === stores.length) {
+ cb();
+ } else {
+ stores[idx].run(value, () => {
+ runStores(stores, value, cb, idx + 1);
+ });
+ }
+}
+
+async function runBenchmark(n) {
+ for (let i = 0; i < n; i++) {
+ // Avoid creating additional ticks.
+ await undefined;
+ }
+}
+
+function main({ n, storageCount }) {
+ const stores = new Array(storageCount).fill(0).map(() => new AsyncLocalStorage());
+ const contextValue = {};
+
+ runStores(stores, contextValue, () => {
+ bench.start();
+ runBenchmark(n).then(() => {
+ bench.end(n);
+ });
+ });
+}