PHPackages                             dragon-code/benchmark - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. dragon-code/benchmark

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

dragon-code/benchmark
=====================

Simple comparison of code execution speed between different options

4.6.1(2mo ago)12037.9k↓45.7%35MITPHPPHP ^8.2CI passing

Since Feb 3Pushed 2w ago3 watchersCompare

[ Source](https://github.com/TheDragonCode/benchmark)[ Packagist](https://packagist.org/packages/dragon-code/benchmark)[ Fund](https://boosty.to/dragon-code)[ Fund](https://yoomoney.ru/to/410012608840929)[ RSS](/packages/dragon-code-benchmark/feed)WikiDiscussions main Synced 2d ago

READMEChangelog (10)Dependencies (7)Versions (47)Used By (5)

Benchmark
=========

[](#benchmark)

  ![Benchmark](https://camo.githubusercontent.com/2790c2c6f1264c2789845423bec6ca245f663ffabee86a016384695a67a880fd/68747470733a2f2f62616e6e6572732e6265796f6e64636f2e64652f42656e63686d61726b2e706e673f7061747465726e3d746f706f677261706879267374796c653d7374796c655f3226666f6e7453697a653d3130307078266d643d312673686f7757617465726d61726b3d31267468656d653d6c69676874267061636b6167654d616e616765723d636f6d706f7365722b726571756972652b2d2d646576267061636b6167654e616d653d647261676f6e2d636f646525324662656e63686d61726b266465736372697074696f6e3d53696d706c652b636f6d70617269736f6e2b6f662b636f64652b657865637574696f6e2b73706565642b6265747765656e2b646966666572656e742b6f7074696f6e7326696d616765733d68747470732533412532462532467777772e7068702e6e6574253246696d616765732532466c6f676f732532466e65772d7068702d6c6f676f2e737667)[![Stable Version](https://camo.githubusercontent.com/19d600c23341c6e1e865fe13d21d51e060e92a3bf66c0b76a02d557eea03195d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f546865447261676f6e436f64652f62656e63686d61726b3f6c6162656c3d737461626c65267374796c653d666c61742d737175617265)](https://packagist.org/packages/dragon-code/benchmark)[![Total Downloads](https://camo.githubusercontent.com/7dd21e1305830f33f9c60339bb9f9d2362d235ae8c977eeade44fc1d8ce6e181/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f647261676f6e2d636f64652f62656e63686d61726b2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/dragon-code/benchmark)[![Github Workflow Status](https://camo.githubusercontent.com/04cdb0ea4a8eb30ebda6849de480524cd31d5345668990a2ca9e915a04fcc479/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f546865447261676f6e436f64652f62656e63686d61726b2f74657374732e796d6c3f7374796c653d666c61742d737175617265)](https://github.com/TheDragonCode/benchmark/actions)[![License](https://camo.githubusercontent.com/3cc7bbc4bb0c0838f406e07a96244aad325fed626887c7fafc02255fa131edaa/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f647261676f6e2d636f64652f62656e63686d61726b2e7376673f7374796c653d666c61742d737175617265)](LICENSE)

Installation
------------

[](#installation)

```
composer require dragon-code/benchmark --dev
```

Usage
-----

[](#usage)

Note

When more than 9 iterations are used, the top and bottom 10% of results are excluded from the average calculation, producing cleaner data less dependent on external factors.

```
use function DragonCode\Benchmark\bench;

bench()
    ->compare(
        foo: fn () => /* some code */,
        bar: fn () => /* some code */,
    )
    ->toConsole();
```

You can use both the `bench()` helper function and the `Benchmark` class (`new Benchmark()` or `Benchmark::make()`).

Callbacks can be passed as an array or as arguments, with or without named keys:

```
use DragonCode\Benchmark\Benchmark;

// As named arguments
new Benchmark()->compare(
    foo: fn () => /* some code */,
    bar: fn () => /* some code */,
)->toConsole();

// As an associative array
bench()->compare([
    'foo' => fn () => /* some code */,
    'bar' => fn () => /* some code */,
])->toConsole();
```

Example output:

```
+-------+-------------------------+-------------------------+
| #     | foo                     | bar                     |
+-------+-------------------------+-------------------------+
| min   | 14.3472 ms - 0 bytes    | 14.3657 ms - 0 bytes    |
| max   | 15.7684 ms - 0 bytes    | 15.7249 ms - 0 bytes    |
| avg   | 15.0967475 ms - 0 bytes | 14.9846725 ms - 0 bytes |
| total | 1207.7398 ms - 0 bytes  | 1198.7738 ms - 0 bytes  |
+-------+-------------------------+-------------------------+
| order | 2                       | 1                       |
+-------+-------------------------+-------------------------+
```

### Iterations Count

[](#iterations-count)

By default, the benchmark performs 100 iterations per callback. Use the `iterations` method to change this. The current iteration number is available as a callback parameter:

```
use DragonCode\Benchmark\Benchmark;

new Benchmark()
    ->iterations(5)
    ->compare(
        foo: fn (int $iteration) => /* some code */,
        bar: fn (int $iteration) => /* some code */,
    )
    ->toConsole();
```

### Warm-up

[](#warm-up)

Use the `warmup` method to run each callback a few times before the measured iterations. Warm-up runs behave identically to regular ones (`beforeEach` / `afterEach` are invoked, the progress bar advances), but their time and memory are not included in the final statistics.

This stabilizes results by absorbing one-time costs such as cold caches, JIT/opcache priming and lazy autoloading.

Disabled by default.

```
use DragonCode\Benchmark\Benchmark;

new Benchmark()
    ->warmup(3) // run 3 warm-up iterations per callback before measuring
    ->compare(
        foo: fn () => /* some code */,
        bar: fn () => /* some code */,
    );
```

### Round Precision

[](#round-precision)

Use the `round` method to set the number of decimal places in console output:

```
new Benchmark()
    ->round(2)
    ->compare(
        foo: fn () => /* some code */,
        bar: fn () => /* some code */,
    )
    ->toConsole();
```

```
+-------+----------------------+----------------------+
| #     | foo                  | bar                  |
+-------+----------------------+----------------------+
| min   | 14.58 ms - 0 bytes   | 14.38 ms - 0 bytes   |
| max   | 15.55 ms - 0 bytes   | 15.71 ms - 0 bytes   |
| avg   | 15.01 ms - 0 bytes   | 15.1 ms - 0 bytes    |
| total | 1201.09 ms - 0 bytes | 1207.76 ms - 0 bytes |
+-------+----------------------+----------------------+
| order | 1                    | 2                    |
+-------+----------------------+----------------------+
```

### Deviation Values

[](#deviation-values)

Use the `deviations` method to measure the deviation between results. All loops will repeat the specified number of times, and the output will include a `deviation` row:

```
new Benchmark()
    ->deviations(4)
    ->compare(
        foo: fn () => /* some code */,
        bar: fn () => /* some code */,
    )
    ->toConsole();
```

```
+------------------+----------------------+-----------------------+
| #                | foo                  | bar                   |
+------------------+----------------------+-----------------------+
| min              | 0.0011 ms - 0 bytes  | 0.0009 ms - 0 bytes   |
| max              | 0.0111 ms - 0 bytes  | 0.0082 ms - 0 bytes   |
| avg              | 0.00453 ms - 0 bytes | 0.002715 ms - 0 bytes |
| total            | 0.0906 ms - 0 bytes  | 0.0543 ms - 0 bytes   |
+------------------+----------------------+-----------------------+
| order            | 2                    | 1                     |
+------------------+----------------------+-----------------------+
| deviation time   | +0.002768            | +0.000919             |
| deviation memory | 0                    | 0                     |
+------------------+----------------------+-----------------------+
```

### Callbacks

[](#callbacks)

You can register callbacks to run before/after the entire benchmark loop or before/after each iteration:

```
use DragonCode\Benchmark\Benchmark;

new Benchmark()
    ->before(fn (int|string $name) => /* once before all iterations of a callback */)
    ->beforeEach(fn (int|string $name, int $iteration) => /* before each iteration */)
    ->after(fn (int|string $name) => /* once after all iterations of a callback */)
    ->afterEach(fn (int|string $name, int $iteration) => /* after each iteration */)
    ->compare(
        fn () => /* some code */,
        fn () => /* some code */,
    )
    ->toConsole();
```

The result of `beforeEach` is passed to the compare callback:

```
new Benchmark()
    ->beforeEach(fn (int|string $name, int $iteration) => /* prepare data */)
    ->compare(
        fn (mixed $before) => /* use $before */,
        fn (mixed $before) => /* use $before */,
    )
    ->toConsole();
```

### Results

[](#results)

#### toConsole

[](#toconsole)

Outputs results to the console:

```
new Benchmark()
    ->round(2)
    ->compare(
        foo: static fn () => /* some code */,
        bar: static fn () => /* some code */,
    )
    ->toConsole();
```

```
+-------+----------------------+----------------------+
| #     | foo                  | bar                  |
+-------+----------------------+----------------------+
| min   | 14.68 ms - 0 bytes   | 14.56 ms - 0 bytes   |
| max   | 15.69 ms - 0 bytes   | 15.64 ms - 0 bytes   |
| avg   | 15.13 ms - 0 bytes   | 15.07 ms - 0 bytes   |
| total | 1210.38 ms - 0 bytes | 1205.26 ms - 0 bytes |
+-------+----------------------+----------------------+
| order | 2                    | 1                     |
+-------+----------------------+----------------------+
```

With deviation values:

```
+------------------+-----------------------+---------------------+
| #                | foo                   | bar                 |
+------------------+-----------------------+---------------------+
| min              | 15.68 ms - 202 bytes  | 2.35 ms - 102 bytes |
| max              | 112.79 ms - 209 bytes | 9.76 ms - 109 bytes |
| avg              | 53.03 ms - 205 bytes  | 5.94 ms - 105 bytes |
| total            | 1696.81 ms - 6.42 KB  | 190.17 ms - 3.30 KB |
+------------------+-----------------------+---------------------+
| order            | 2                     | 1                   |
+------------------+-----------------------+---------------------+
| deviation time   | +0.100715             | +0.114023           |
| deviation memory | 0                     | 0                   |
+------------------+-----------------------+---------------------+
```

#### toData

[](#todata)

Returns results as an array of `DragonCode\Benchmark\Data\ResultData` DTO objects:

```
return new Benchmark()
    ->deviations()
    ->compare(
        foo: fn () => /* some code */,
        bar: fn () => /* some code */,
    )
    ->toData();
```

```
array:2 [
  "foo" => DragonCode\Benchmark\Data\ResultData {#23
    +min: DragonCode\Benchmark\Data\MetricData {#64
      +time: 0.001
      +memory: 0.0
    }
    +max: DragonCode\Benchmark\Data\MetricData {#65
      +time: 0.0036
      +memory: 0.0
    }
    +avg: DragonCode\Benchmark\Data\MetricData {#66
      +time: 0.0024209375
      +memory: 0.0
    }
    +total: DragonCode\Benchmark\Data\MetricData {#67
      +time: 0.7747
      +memory: 0.0
    }
    +deviation: DragonCode\Benchmark\Data\DeviationData {#68
      +percent: DragonCode\Benchmark\Data\MetricData {#69
        +time: 0.0007048383984778
        +memory: 0.0
      }
    }
  }
  "bar" => DragonCode\Benchmark\Data\ResultData {#70
    +min: DragonCode\Benchmark\Data\MetricData {#71
      +time: 0.001
      +memory: 0.0
    }
    +max: DragonCode\Benchmark\Data\MetricData {#72
      +time: 0.0032
      +memory: 0.0
    }
    +avg: DragonCode\Benchmark\Data\MetricData {#73
      +time: 0.00242875
      +memory: 0.0
    }
    +total: DragonCode\Benchmark\Data\MetricData {#74
      +time: 0.7772
      +memory: 0.0
    }
    +deviation: DragonCode\Benchmark\Data\DeviationData {#75
      +percent: DragonCode\Benchmark\Data\MetricData {#76
        +time: 0.00061642429076895
        +memory: 0.0
      }
    }
  }
]
```

#### toAssert

[](#toassert)

Validates benchmark results against expected thresholds. Both `from` and `till` parameters are optional — use one or both:

```
use DragonCode\Benchmark\Benchmark;

new Benchmark()
    ->compare(/* ... */)
    ->toAssert()

    ->toBeMinTime(from: 0.5, till: 3)       // between 0.5 and 3 ms
    ->toBeMaxTime(from: 0.5, till: 3)       // between 0.5 and 3 ms
    ->toBeAvgTime(from: 0.5, till: 3)       // between 0.5 and 3 ms
    ->toBeTotalTime(from: 0.5, till: 9)     // between 0.5 and 9 ms

    ->toBeMinMemory(from: 0, till: 1024)    // between 0 and 1024 bytes
    ->toBeMaxMemory(from: 0, till: 1024)    // between 0 and 1024 bytes
    ->toBeAvgMemory(from: 0, till: 1024)    // between 0 and 1024 bytes
    ->toBeTotalMemory(from: 0, till: 4096)  // between 0 and 4096 bytes

    ->toBeDeviationTime(from: -0.5, till: 0.5)   // deviation between -0.5% and 0.5%
    ->toBeDeviationMemory(from: -2.5, till: 2.5); // deviation between -2.5% and 2.5%
```

### Regression Testing

[](#regression-testing)

Detects performance regressions by comparing current results to a saved baseline (snapshot).

#### How To Work

[](#how-to-work)

- **First run:** no `.snap` files exist — results are written to disk, no check is performed.
- **Next runs:** results are compared to the snapshot; exceeding `$max` percent throws an `AssertionError`.
- **Location:** snapshots are stored per call site (subdirectory derived from the caller file and line).

Note

Delete the corresponding `.snap` files to reset the baseline — the next run will recreate them.

#### Configuring the Snapshot Directory

[](#configuring-the-snapshot-directory)

Set the snapshot directory via `snapshots()`. Default: `./.benchmarks`.

```
use DragonCode\Benchmark\Benchmark;

new Benchmark()
    ->snapshots(directory: __DIR__ . '/.benchmarks')
    // ...
    ->toAssert()
    ->toBeRegressionTime(max: 10)
    ->toBeRegressionMemory(max: 10);
```

Tip

Commit the generated snapshot files to version control to keep regression checks consistent across environments and CI.

#### toBeRegressionTime

[](#toberegressiontime)

Fails if execution time exceeds the snapshot by more than `$max` percent.

```
use DragonCode\Benchmark\Benchmark;

new Benchmark()
    // ...
    ->toAssert()
    ->toBeRegressionTime(max: 15); // allow up to 15% time regression
```

#### toBeRegressionMemory

[](#toberegressionmemory)

Fails if memory usage exceeds the snapshot by more than `$max` percent.

```
use DragonCode\Benchmark\Benchmark;

new Benchmark()
    // ...
    ->toAssert()
    ->toBeRegressionMemory(max: 15); // allow up to 15% memory regression
```

### Disable Progress Bar

[](#disable-progress-bar)

```
use DragonCode\Benchmark\Benchmark;

new Benchmark()
    ->disableProgressBar()
    // ...
```

License
-------

[](#license)

This package is licensed under the [MIT License](LICENSE).

###  Health Score

61

—

FairBetter than 98% of packages

Maintenance93

Actively maintained with recent releases

Popularity43

Moderate usage in the ecosystem

Community23

Small or concentrated contributor base

Maturity71

Established project with proven stability

 Bus Factor1

Top contributor holds 88.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~31 days

Recently: every ~18 days

Total

39

Last Release

63d ago

Major Versions

v1.5.1 → v2.0.02023-02-06

2.x-dev → 3.0.02024-03-23

3.x-dev → 4.0.02026-02-14

PHP version history (2 changes)v1.0.0PHP ^8.1

3.0.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/b77790e612f1c9beed1e1533e36eba4954fbd6da2a5c9f71e845cd0f5465f0ad?d=identicon)[Helldar](/maintainers/Helldar)

---

Top Contributors

[![andrey-helldar](https://avatars.githubusercontent.com/u/10347617?v=4)](https://github.com/andrey-helldar "andrey-helldar (360 commits)")[![actions-user](https://avatars.githubusercontent.com/u/65916846?v=4)](https://github.com/actions-user "actions-user (20 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (17 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (7 commits)")[![Copilot](https://avatars.githubusercontent.com/in/1143301?v=4)](https://github.com/Copilot "Copilot (3 commits)")[![roxblnfk](https://avatars.githubusercontent.com/u/4152481?v=4)](https://github.com/roxblnfk "roxblnfk (1 commits)")

---

Tags

benchmarkcomparatorcomparatorscomparisoncomparison-toolruntimespeedspeedtesttimetimercomparatortimetimercomparisonruntimebenchmarkspeedcomparatorsspeedtestcomparison-tool

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/dragon-code-benchmark/health.svg)

```
[![Health](https://phpackages.com/badges/dragon-code-benchmark/health.svg)](https://phpackages.com/packages/dragon-code-benchmark)
```

###  Alternatives

[illuminate/support

The Illuminate Support package.

630113.0M41.3k](/packages/illuminate-support)[illuminate/container

The Illuminate Container package.

31182.0M2.4k](/packages/illuminate-container)[illuminate/collections

The Illuminate Collections package.

27078.0M1.1k](/packages/illuminate-collections)[ayesh/php-timer

High-resolution and monotonic stop-watch for all your needs. Supports timer start, pause, resume, stop, read, and minimal conversion.

25235.3k13](/packages/ayesh-php-timer)[phootwork/lang

Missing PHP language constructs

1228.2M8](/packages/phootwork-lang)[icecave/chrono

A date &amp; time library that is decoupled from the system clock.

56195.7k7](/packages/icecave-chrono)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
