-
-
Notifications
You must be signed in to change notification settings - Fork 34.9k
Description
Version
v14.20.0, v16.16.0, v18.7.0
Platform
Darwin MacBook-Pro-5.localdomain 21.5.0 Darwin Kernel Version 21.5.0: Tue Apr 26 21:08:37 PDT 2022; root:xnu-8020.121.3~4/RELEASE_ARM64_T6000 arm64
Subsystem
No response
What steps will reproduce the bug?
See repro repo at https://github.com/achingbrain/esm-vs-cjs
How often does it reproduce? Is there a required condition?
Every time
What is the expected behavior?
ESM and CJS classes should have similar performance characteristics instead of ESM being 10x slower than CJS.
What do you see instead?
ESM classes are 10x slower than CJS classes.
Additional information
I was porting some CJS code to ESM and benchmarking it to ensure I hadn't accidentally removed any performance optimisations but the ESM code was always significantly slower. I started removing functionality to narrow down where the bottleneck was but I still couldn't find it.
Eventually I ended up with a benchmark suite that did pretty much nothing, yet the CJS version of the same code was still massively faster than the ESM version, so I created a fresh benchmark suite that just instantiated a class and called a simple method and 😮 it turns out ESM performance is quite poor compared to CJS, and CJS has taken a big dip in node 18.
Benchmark data:
Node 14
% node index.js
esm x 106,756,363 ops/sec ±0.15% (93 runs sampled)
cjs x 993,925,878 ops/sec ±0.17% (93 runs sampled)
Fastest is cjsNode 16
% node index.js
esm x 156,061,934 ops/sec ±0.19% (94 runs sampled)
cjs x 1,034,861,972 ops/sec ±0.19% (97 runs sampled)
Fastest is cjsNode 18
% node index.js
esm x 144,767,462 ops/sec ±0.35% (93 runs sampled)
cjs x 388,040,620 ops/sec ±0.25% (100 runs sampled)
Fastest is cjs