-
-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Description
Version
29.7.0
Steps to reproduce
The following snippet includes a set of example calls to native/global APIs (modules? globals objects? not sure what do you call them - Number, Math, Array), and a few simple expressions (equality check, and some multiplication) for comparison:
const ITERATIONS = 100000000
let start = Date.now();
for (let i = 0; i < ITERATIONS; i++) {
Number.isNaN(i)
}
console.log(Date.now() - start);
start = Date.now();
for (let i = 0; i < ITERATIONS; i++) {
Array.isArray(i);
}
console.log(Date.now() - start);
start = Date.now();
for (let i = 0; i < ITERATIONS; i++) {
Math.max(i, i-1);
}
console.log(Date.now() - start);
start = Date.now();
for (let i = 0; i < ITERATIONS; i++) {
i !== i
}
console.log(Date.now() - start);
start = Date.now();
for (let i = 0; i < ITERATIONS; i++) {
i * (i-1)
}
console.log(Date.now() - start);Running with plain NodeJS yields results within a few ms:
> node index.test.js
52
63
48
47
64
Running with jest however yields significant performance drawbacks for the native objects:
> node ./node_modules/.bin/jest index.test.js
console.log
11252
at Object.<anonymous> (index.test.js:7:9)
console.log
11080
at Object.<anonymous> (index.test.js:13:9)
console.log
11176
at Object.<anonymous> (index.test.js:19:9)
console.log
48
at Object.<anonymous> (index.test.js:25:9)
console.log
63
at Object.<anonymous> (index.test.js:31:9)
This happens even when transformation and code coverage is explicitly disable via jest config:
export default {
collectCoverage: false,
collectCoverageFrom: [],
transform: {},
}Expected behavior
I expect Number.isNaN and other native APIs to run as usual
Actual behavior
Number.isNaN and other native APIs are ~20x slower within jest runtime
Additional context
I tried jest versions all the way down to jest@12, as well as jest@30.0.0-alpha.7, no change.
Profiling hints at _execModule in jest-runtime (that is, if node --prof captures the correct process):
ticks parent name
26056 93.7% UNKNOWN
25262 97.0% JS: *Object.<anonymous> .../index.test.js:1:114
25262 100.0% JS: ^_execModule .../node_modules/jest-runtime/build/index.js:1364:14
25262 100.0% JS: ^_loadModule .../node_modules/jest-runtime/build/index.js:1000:14
25262 100.0% JS: ^requireModule .../node_modules/jest-runtime/build/index.js:812:16
25262 100.0% JS: ~jestAdapter .../node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:16:21
Assigning for example Number.isNaN to a variable and calling instead that make the code execute fast again:
const myNaN = Number.isNaN;
myNaN(3);Environment
System:
OS: macOS 14.7.2
CPU: (10) arm64 Apple M1 Pro
Binaries:
Node: 20.11.1 - ~/Library/Caches/fnm_multishells/73147_1739329875570/bin/node
Yarn: 1.22.21 - ~/Library/Caches/fnm_multishells/73147_1739329875570/bin/yarn
npm: 10.2.4 - ~/Library/Caches/fnm_multishells/73147_1739329875570/bin/npm
npmPackages:
jest: ^29.7.0 => 29.7.0