SIGN IN SIGN UP
oven-sh / bun UNCLAIMED

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one

0 0 150 Rust

Add microbenchmarks for latest JSC changes (#31562)

This PR adds microbenchmarks for latest JSC changes

---


Comparison of Bun 1.3.14 (WebKit `5488984d`) and Bun main (WebKit
`0d85951a`), on Apple Silicon macOS.
Numbers are mitata average time per iteration of the snippet, using the
benchmarks in `bench/snippets/` (`BENCHMARK_RUNNER=1 <bun>
bench/snippets/<file>.mjs`).

> [!NOTE]
> The code snippets shown in each section are simplified excerpts for
illustration only. The actual measurements were taken with the benchmark
files added in this PR.

## `Array#indexOf` / `Array#includes` (string arrays)

```js
const arr = Array.from({ length: 64 }, (_, i) => String.fromCharCode(65 + (i % 26)) + "x".repeat(63));
const key = "@" + "x".repeat(63);

let result = 0;
for (let i = 0; i < 1e4; i++) result += arr.indexOf(key);
```

| version | time |
| ------- | -------- |
| 1.3.14  | 13.12 ms |
| main    | 2.00 ms  |

6.6 times faster (`includes`: 11.96 ms → 2.03 ms, 5.9 times faster)

upstream commits: https://commits.webkit.org/313389@main,
https://commits.webkit.org/312963@main by sosukesuzuki

## `Object.defineProperty`

```js
const o = {};
Object.defineProperty(o, "hey", { value: 42, writable: true, enumerable: true, configurable: true });
```

| version | time    |
| ------- | ------- |
| 1.3.14  | 38.9 ns |
| main    | 4.5 ns  |

8.6 times faster (accessor descriptor: 1.6x, getter only: 1.4x, 4
properties in a row: 3.1x)

upstream commit: https://commits.webkit.org/313124@main by Constellation

## `Promise.all` with non-thenable values

```js
const values = Array.from({ length: 1000 }, (_, i) => i);
await Promise.all(values);
```

| version | time     |
| ------- | -------- |
| 1.3.14  | 24.46 µs |
| main    | 15.29 µs |

1.6 times faster (`Promise.race([p1, p2])`: 1.35x)

upstream commits: https://commits.webkit.org/313576@main,
https://commits.webkit.org/313361@main by sosukesuzuki

## `Promise#then` chain

```js
let p = Promise.resolve(0);
for (let i = 0; i < 10; i++) p = p.then(v => v + 1);
await p;
```

| version | time     |
| ------- | -------- |
| 1.3.14  | 296.1 ns |
| main    | 228.1 ns |

1.3 times faster

upstream commits: https://commits.webkit.org/313220@main,
https://commits.webkit.org/313277@main by Constellation,
https://commits.webkit.org/313294@main by sosukesuzuki

## Memory per pending `Promise` with one `.then` handler

```js
const p = new Promise(() => {});
p.then(v => v);
// keep p alive, measure heap size after GC
```

| version | heap per promise |
| ------- | ---------------- |
| 1.3.14  | 104 bytes        |
| main    | 72 bytes         |

31% less memory (the promise reaction cell is no longer allocated for
the first `.then`)

upstream commit: https://commits.webkit.org/313220@main by Constellation

## `String#startsWith` / `String#endsWith` with a constant search string

```js
// urls: 64 different strings
let count = 0;
for (let i = 0; i < urls.length; i++) count += urls[i].startsWith("https://");
```

| version | time     |
| ------- | -------- |
| 1.3.14  | 314.5 ns |
| main    | 68.4 ns  |

4.6 times faster (`endsWith`: 316.4 ns → 70.2 ns, 4.5 times faster)

upstream commit: https://commits.webkit.org/313394@main by sosukesuzuki

## `String#split`

```js
// sentences: 64 different ~90-char strings
sentences[i].split(" ");
```

| version | time     |
| ------- | -------- |
| 1.3.14  | 63.98 µs |
| main    | 20.85 µs |

3.1 times faster (`split(",")` on short CSV lines: 1.9 times faster)

upstream commit: https://commits.webkit.org/312843@main by sosukesuzuki

## `String#match`

```js
// sentences: 64 different ~90-char strings
sentences[i].match(/[a-z]+/g);
```

| version | time     |
| ------- | -------- |
| 1.3.14  | 50.54 µs |
| main    | 15.84 µs |

3.2 times faster (non-global regexp with a capture group: 2.7 times
faster)

upstream commit: https://commits.webkit.org/313363@main by sosukesuzuki

## `String#substring`

```js
// urls: 64 different strings
urls[i].substring(8, 24);
```

| version | time     |
| ------- | -------- |
| 1.3.14  | 789.1 ns |
| main    | 354.2 ns |

2.2 times faster

upstream commit: https://commits.webkit.org/313402@main by Constellation

## `TypedArray#sort`

```js
const floats = Float64Array.from({ length: 1024 }, () => Math.random() * 1000);
floats.slice().sort();
```

| version | time     |
| ------- | -------- |
| 1.3.14  | 16.84 µs |
| main    | 7.25 µs  |

2.3 times faster (Int32Array: 1.9x, with a comparator: 2.0x)

upstream commit: https://commits.webkit.org/312803@main by syg

## `Array#sort` (small arrays)

```js
// 64 unsorted numbers
numbers.sort((a, b) => a - b);
```

| version | time     |
| ------- | -------- |
| 1.3.14  | 1.02 µs  |
| main    | 774.4 ns |

1.3 times faster

upstream commit: https://commits.webkit.org/312983@main by Constellation

## `Array#concat`

```js
const a = Array.from({ length: 128 }, (_, i) => i);
const b = Array.from({ length: 128 }, (_, i) => i + 128);
a.concat(b);
```

| version | time    |
| ------- | ------- |
| 1.3.14  | 67.6 ns |
| main    | 55.5 ns |

1.2 times faster (small int arrays: 1.3x, string arrays: 1.2x)

upstream commit: https://commits.webkit.org/312543@main by Constellation

## String equality (16-bit / non-Latin1 strings)

```js
// two distinct 256-char strings with identical 16-bit content
function eq(x, y) {
  return x === y;
}
let n = 0;
for (let i = 0; i < 1e6; ++i) {
  if (eq(a, b)) n++;
  if (eq(a, c)) n++;
}
```

| version | time     |
| ------- | -------- |
| 1.3.14  | 11.46 ms |
| main    | 8.78 ms  |

1.3 times faster (65-char strings: 5.62 ms → 4.20 ms, 1.3 times faster)

upstream commit: https://commits.webkit.org/312931@main by sosukesuzuki

## `Date.now()`

```js
let sum = 0;
for (let i = 0; i < 1e6; ++i) sum += Date.now();
```

| version | time     |
| ------- | -------- |
| 1.3.14  | 22.27 ms |
| main    | 19.18 ms |

1.2 times faster (elapsed-time pattern `Date.now() - start`: 25.02 ms →
19.80 ms, 1.3 times faster)

upstream commit: https://commits.webkit.org/313578@main by sosukesuzuki

## `Array#unshift`

```js
const arr = [];
for (let i = 0; i < 16; i++) arr.unshift(i);
```

| version | time     |
| ------- | -------- |
| 1.3.14  | 268.4 ns |
| main    | 215.2 ns |

1.2 times faster

upstream commits: https://commits.webkit.org/313475@main,
https://commits.webkit.org/312915@main by Constellation

## Async module graphs (top-level await)

```sh
# 50,000 synchronous ES modules importing one module with top-level await
cd bench/module-loader
CASCADE_CHAINS=500 CASCADE_DEPTH=100 bun create-tla-graph.js
bun ./tla-cascade-entry.mjs
```

| version | time    |
| ------- | ------- |
| 1.3.14  | ~1.9 s  |
| main    | ~1.25 s |

~1.5 times faster (GatherAvailableAncestors is now O(N) instead of
O(N²))

upstream commit: https://commits.webkit.org/312498@main by sosukesuzuki
S
SUZUKI Sosuke committed
2629789a22bd9fcd5137dc42d8a1865870aa992f
Parent: 61bd997
Committed by GitHub <noreply@github.com> on 5/31/2026, 6:07:34 PM