From 20f9dbc2865188e8743982937f51a919510d7978 Mon Sep 17 00:00:00 2001 From: pshu Date: Wed, 10 Jun 2026 10:36:44 +0800 Subject: [PATCH] bench(resolver): add napi-sync scenario (block_on per resolve) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing scenarios drive resolution inside a long-lived tokio runtime with the whole batch in one async block (or a JoinSet). The most common real consumer — @rspack/resolver's NAPI `.sync()` API — instead runs one `Handle::current().block_on(resolve(...))` per call. Add a scenario that mirrors that per-call block_on so the bench reflects how synchronous consumers actually invoke the resolver. --- benches/resolver.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/benches/resolver.rs b/benches/resolver.rs index 87f0cf50..acc5ac0e 100644 --- a/benches/resolver.rs +++ b/benches/resolver.rs @@ -284,6 +284,35 @@ fn bench_resolver(c: &mut Criterion) { }, ); + // Models the `@rspack/resolver` (NAPI) `.sync()` entry point — the common npm + // path — which runs one `Handle::current().block_on(resolve(...))` per call. + // Unlike `single-thread` (a single async block over the whole batch), every + // resolve enters and exits the runtime on its own, matching how a synchronous + // consumer (rspack injecting the resolver, or a direct `.sync()` caller) + // actually invokes it. + group.bench_with_input( + BenchmarkId::from_parameter("napi-sync (block_on per resolve)"), + &data, + |b, data| { + let runner = runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("failed to create tokio runtime"); + let rspack_resolver = rspack_resolver(false); + + b.iter_with_setup( + || { + rspack_resolver.clear_cache(); + }, + |_| { + for (path, request) in data { + let _ = runner.block_on(rspack_resolver.resolve(path, request)); + } + }, + ); + }, + ); + group.bench_with_input( BenchmarkId::from_parameter("[single-threaded]resolve with many extensions"), &data,