0
# Benchmarking
1
2
Vitest provides built-in benchmarking capabilities for measuring and comparing code performance with statistical analysis.
3
4
## Capabilities
5
6
### Benchmark Definition
7
8
Define benchmarks similar to tests using the `bench` function.
9
10
```typescript { .api }
11
/**
12
* Define a benchmark
13
* @param name - Benchmark name/description
14
* @param fn - Benchmark function to measure
15
* @param options - Optional benchmark options
16
*/
17
function bench(
18
name: string,
19
fn: BenchFunction,
20
options?: BenchOptions
21
): void;
22
23
interface BenchFunction {
24
/**
25
* Benchmark implementation
26
* @param options - Iteration options
27
*/
28
(options: { count: number }): void | Promise<void>;
29
}
30
31
interface BenchOptions {
32
/** Number of times to run the benchmark */
33
time?: number;
34
35
/** Number of iterations */
36
iterations?: number;
37
38
/** Warmup time in ms */
39
warmupTime?: number;
40
41
/** Warmup iterations */
42
warmupIterations?: number;
43
}
44
```
45
46
**Usage:**
47
48
```typescript
49
import { bench, describe } from 'vitest';
50
51
describe('array operations', () => {
52
bench('push', () => {
53
const arr: number[] = [];
54
for (let i = 0; i < 1000; i++) {
55
arr.push(i);
56
}
57
});
58
59
bench('spread', () => {
60
let arr: number[] = [];
61
for (let i = 0; i < 1000; i++) {
62
arr = [...arr, i];
63
}
64
});
65
66
bench('concat', () => {
67
let arr: number[] = [];
68
for (let i = 0; i < 1000; i++) {
69
arr = arr.concat(i);
70
}
71
});
72
});
73
```
74
75
### Benchmark Modifiers
76
77
Benchmark functions support modifiers similar to tests.
78
79
```typescript { .api }
80
interface BenchmarkAPI {
81
/** Run only this benchmark */
82
only: BenchmarkAPI;
83
84
/** Skip this benchmark */
85
skip: BenchmarkAPI;
86
87
/** Mark benchmark as todo */
88
todo: BenchmarkAPI;
89
90
/** Skip benchmark if condition is true */
91
skipIf(condition: boolean): BenchmarkAPI;
92
93
/** Run benchmark only if condition is true */
94
runIf(condition: boolean): BenchmarkAPI;
95
}
96
```
97
98
**Usage:**
99
100
```typescript
101
import { bench } from 'vitest';
102
103
bench.only('focused benchmark', () => {
104
// Only this runs
105
});
106
107
bench.skip('skipped benchmark', () => {
108
// This is skipped
109
});
110
111
bench.todo('implement later');
112
113
bench.skipIf(process.platform === 'win32')('Unix only', () => {
114
// Runs only on non-Windows
115
});
116
```
117
118
### Async Benchmarks
119
120
Benchmark async operations.
121
122
```typescript
123
import { bench } from 'vitest';
124
125
bench('async operation', async () => {
126
await fetchData();
127
});
128
129
bench('promise chain', async () => {
130
await fetch('/api/data')
131
.then(res => res.json())
132
.then(data => processData(data));
133
});
134
```
135
136
### Benchmark with Setup/Teardown
137
138
Use lifecycle hooks for setup and teardown.
139
140
```typescript
141
import { bench, describe, beforeEach, afterEach } from 'vitest';
142
143
describe('database operations', () => {
144
let db;
145
146
beforeEach(async () => {
147
db = await connectToDatabase();
148
await db.seed();
149
});
150
151
afterEach(async () => {
152
await db.close();
153
});
154
155
bench('query users', async () => {
156
await db.query('SELECT * FROM users');
157
});
158
159
bench('insert user', async () => {
160
await db.insert('users', { name: 'John' });
161
});
162
});
163
```
164
165
### Benchmark Options
166
167
Control benchmark execution with options.
168
169
```typescript
170
import { bench } from 'vitest';
171
172
bench('custom options', () => {
173
// benchmark code
174
}, {
175
time: 5000, // Run for 5 seconds
176
iterations: 100, // Run 100 iterations
177
warmupTime: 1000, // Warmup for 1 second
178
warmupIterations: 10 // 10 warmup iterations
179
});
180
```
181
182
## Benchmark Utilities
183
184
### Get Benchmark Context
185
186
Access benchmark function and options from suite utilities.
187
188
```typescript { .api }
189
/**
190
* Get the benchmark function
191
* @returns Benchmark function
192
*/
193
function getBenchFn(): BenchFunction;
194
195
/**
196
* Get the benchmark options
197
* @returns Benchmark options
198
*/
199
function getBenchOptions(): BenchOptions;
200
```
201
202
**Usage:**
203
204
```typescript
205
import { getBenchFn, getBenchOptions } from 'vitest/suite';
206
207
const benchFn = getBenchFn();
208
const options = getBenchOptions();
209
```
210
211
## Running Benchmarks
212
213
Run benchmarks with the `--mode benchmark` flag:
214
215
```bash
216
vitest bench
217
# or
218
vitest --mode benchmark
219
```
220
221
## Benchmark Configuration
222
223
Configure benchmarking in vitest.config.ts:
224
225
```typescript
226
import { defineConfig } from 'vitest/config';
227
228
export default defineConfig({
229
test: {
230
benchmark: {
231
include: ['**/*.bench.ts'],
232
exclude: ['node_modules'],
233
outputFile: './bench-results.json',
234
reporters: ['default', 'verbose']
235
}
236
}
237
});
238
```
239
240
## Benchmark Reporters
241
242
Vitest provides specialized benchmark reporters:
243
244
```typescript { .api }
245
class BenchmarkReporter {
246
onInit(ctx: Vitest): void;
247
onFinished(files?: File[], errors?: unknown[]): Promise<void> | void;
248
}
249
250
class VerboseBenchmarkReporter extends BenchmarkReporter {
251
// Detailed benchmark output
252
}
253
```
254
255
## Benchmark Results
256
257
Benchmark results include statistical analysis:
258
259
```typescript { .api }
260
interface BenchmarkResult {
261
/** Benchmark name */
262
name: string;
263
264
/** Number of operations per second */
265
hz: number;
266
267
/** Minimum execution time */
268
min: number;
269
270
/** Maximum execution time */
271
max: number;
272
273
/** Mean execution time */
274
mean: number;
275
276
/** Median execution time */
277
median: number;
278
279
/** Standard deviation */
280
sd: number;
281
282
/** Margin of error */
283
moe: number;
284
285
/** Relative margin of error */
286
rme: number;
287
288
/** Sample size */
289
samples: number[];
290
}
291
```
292
293
## Common Patterns
294
295
### Comparing Implementations
296
297
```typescript
298
import { bench, describe } from 'vitest';
299
300
describe('string concatenation', () => {
301
const parts = ['a', 'b', 'c', 'd', 'e'];
302
303
bench('plus operator', () => {
304
let result = '';
305
for (const part of parts) {
306
result += part;
307
}
308
});
309
310
bench('array join', () => {
311
parts.join('');
312
});
313
314
bench('template literal', () => {
315
`${parts[0]}${parts[1]}${parts[2]}${parts[3]}${parts[4]}`;
316
});
317
});
318
```
319
320
### Testing Different Data Sizes
321
322
```typescript
323
import { bench, describe } from 'vitest';
324
325
for (const size of [10, 100, 1000, 10000]) {
326
describe(`array operations (size: ${size})`, () => {
327
const data = Array.from({ length: size }, (_, i) => i);
328
329
bench('map', () => {
330
data.map(x => x * 2);
331
});
332
333
bench('forEach', () => {
334
const result: number[] = [];
335
data.forEach(x => result.push(x * 2));
336
});
337
338
bench('for loop', () => {
339
const result: number[] = [];
340
for (let i = 0; i < data.length; i++) {
341
result.push(data[i] * 2);
342
}
343
});
344
});
345
}
346
```
347
348
## Type Definitions
349
350
```typescript { .api }
351
type BenchFunction = (options: { count: number }) => void | Promise<void>;
352
353
interface BenchOptions {
354
time?: number;
355
iterations?: number;
356
warmupTime?: number;
357
warmupIterations?: number;
358
}
359
360
interface BenchTask {
361
name: string;
362
fn: BenchFunction;
363
options: BenchOptions;
364
result?: BenchmarkResult;
365
}
366
367
interface Benchmark extends BenchTask {
368
meta: Record<string, any>;
369
}
370
```
371