PHPackages                             pyrsmk/streetfight - 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. pyrsmk/streetfight

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

pyrsmk/streetfight
==================

A simple benchmarking tool

6.0.4(6y ago)06[2 PRs](https://github.com/pyrsmk/StreetFight/pulls)MITPHPPHP &gt;=7.2.0

Since Aug 17Pushed 4y ago1 watchersCompare

[ Source](https://github.com/pyrsmk/StreetFight)[ Packagist](https://packagist.org/packages/pyrsmk/streetfight)[ RSS](/packages/pyrsmk-streetfight/feed)WikiDiscussions master Synced yesterday

READMEChangelogDependencies (3)Versions (28)Used By (0)

StreetFight
===========

[](#streetfight)

StreetFight is a benchmarking tool aiming to quickly know what code have better performance against another one. It is not intended to be an exhaustive profiling library and probably won't grow any further.

Note that StreetFight is following the [Elegant Objects](https://www.elegantobjects.org/) principle, and uses some functional programming internally with the help of [Funktions](https://github.com/pyrsmk/Funktions).

Install
-------

[](#install)

StreetFight requires PHP 7.2.

```
composer require pyrsmk/streetfight

```

Example
-------

[](#example)

Here's the common way to execute a benchmark and retrieve a report directly from it. This example compares the performance of pre-increment and post-increment instructions.

```
use StreetFight\Challenger\Challenger;
use StreetFight\Challenger\ChallengerList;
use StreetFight\Round\Round;
use StreetFight\Match\AutoTimedMatch;
use StreetFight\Report\Report;
use StreetFight\Report\PercentageReport;
use StreetFight\Report\DescSortedReport;

$report =
    // Sort the report in descending direction
    new DescSortedReport(
        // Convert the seconds report to percentage
        new PercentageReport(
            // Create a report to process match results
            new Report(
                // Create a match to process the benchmark for a certain time
                // (here, AutoTimedMatch will compute automatically the time of the match)
                // (see below for types of match)
                new AutoTimedMatch(
                    // A typical round...
                    new Round(
                        // ...with a challenger list
                        new ChallengerList(
                            new Challenger('Pre-increment', function () {
                                $i = 0;
                                ++$i;
                            }),
                            new Challenger('Post-increment', function () {
                                $i = 0;
                                $i++;
                            })
                        )
                    )
                )
            )
        )
    );

var_dump($report->asPercentages());
/*
    [
        'Post-increment' => 100,
        'Pre-increment' => 98.84
    ]
*/
```

Match objects
-------------

[](#match-objects)

There are 3 types of matches:

- `StreetFight\Match\Match(int $rounds, RoundInterface $round)`: it will take a number of rounds to run, and a `StreetFight\Round\Round` object
- `StreetFight\Match\TimedMatch(int $time, RoundInterface $round)`: it will take a minimum time in milliseconds while the benchmark will run, and a `StreetFight\Round\Round` object
- `StreetFight\Match\AutoTimedMatch(RoundInterface $round)`: contrary to `TimedMatch`, it will automatically compute the maximum time for the benchmark to run, and only accepts a `StreetFight\Round\Round` object as parameter

```
use StreetFight\Challenger\Challenger;
use StreetFight\Challenger\ChallengerList;
use StreetFight\Round\Round;
use StreetFight\Match\Match;

new Match(
    100, // Will iterate 100 times
    new Round(
        new ChallengerList(
            new Challenger('Pre-increment', function () {
                $i = 0;
                ++$i;
            }),
            new Challenger('Post-increment', function () {
                $i = 0;
                $i++;
            })
        )
    )
)
```

```
use StreetFight\Challenger\Challenger;
use StreetFight\Challenger\ChallengerList;
use StreetFight\Round\Round;
use StreetFight\Match\TimedMatch;

new TimedMatch(
    5000, // Will run for 5 seconds at least
    new Round(
        new ChallengerList(
            new Challenger('Pre-increment', function () {
                $i = 0;
                ++$i;
            }),
            new Challenger('Post-increment', function () {
                $i = 0;
                $i++;
            })
        )
    )
)
```

```
use StreetFight\Challenger\Challenger;
use StreetFight\Challenger\ChallengerList;
use StreetFight\Round\Round;
use StreetFight\Match\AutoTimedMatch;

// The recommended and simplest way to run the benchmark
new AutoTimedMatch(
    new Round(
        new ChallengerList(
            new Challenger('Pre-increment', function () {
                $i = 0;
                ++$i;
            }),
            new Challenger('Post-increment', function () {
                $i = 0;
                $i++;
            })
        )
    )
)
```

Report objects
--------------

[](#report-objects)

There are several types of `Report` objects:

- `StreetFight\Report\Report(MatchInterface $match)`: the main `Report` object, can only take a `Match` object as parameter; the results are returned as raw seconds
- `StreetFight\Report\RoundedSecondsReport`: a decorator for the main `Report` object; the results are returned as seconds rounded to 2 decimal digits
- `StreetFight\Report\MillisecondsReport`: a decorator for the main `Report` object; the results are returned as milliseconds
- `StreetFight\Report\MicrosecondsReport`: a decorator for the main `Report` object; the results are returned as microseconds
- `StreetFight\Report\PercentageReport`: a decorator for the main `Report` object; the results are returned in percentage
- `StreetFight\Report\AscSortedReport`: a decorator that sorts a report in ascending direction
- `StreetFight\Report\DescSortedReport`: a decorator that sorts a report in descending direction

```
use StreetFight\Challenger\Challenger;
use StreetFight\Challenger\ChallengerList;
use StreetFight\Round\Round;
use StreetFight\Match\AutoTimedMatch;
use StreetFight\Report\Report;
use StreetFight\Report\MicrosecondsReport;
use StreetFight\Report\AscSortedReport;

// Sort the report
new AscSortedReport(
    // Format the report results in microseconds
    new MicrosecondsReport(
        // The main Report object
        new Report(
            new AutoTimedMatch(
                new Round(
                    new ChallengerList(
                        new Challenger('Pre-increment', function () {
                            $i = 0;
                            ++$i;
                        }),
                        new Challenger('Post-increment', function () {
                            $i = 0;
                            $i++;
                        })
                    )
                )
            )
        )
    )
)
```

Set BEFORE and AFTER hooks
--------------------------

[](#set-before-and-after-hooks)

If you need to run some specific routines, you can set them in the `Round` object:

```
use StreetFight\Challenger\Challenger;
use StreetFight\Challenger\ChallengerList;
use StreetFight\Round\Round;
use StreetFight\Hook\Hook;

new Round(
    new ChallengerList(
        new Challenger('file_put_contents (overwrite)', function () {
            file_put_contents('foo.txt', 'bar');
        }),
        new Challenger('fwrite (overwrite)', function () {
            $f = fopen('foo.txt', 'w');
            fwrite($f, 'bar');
            fclose($f);
        }),
        new Challenger('file_put_contents (append)', function () {
            file_put_contents('foo.txt', 'bar', FILE_APPEND);
        }),
        new Challenger('fwrite (append)', function () {
            $f = fopen('foo.txt', 'a');
            fwrite($f, 'bar');
            fclose($f);
        }),
    ),
    // Set a hook that will be run BEFORE each task of each iteration
    new Hook(function () {
        touch('foo.txt');
    }),
    // Set a hook that will be run AFTER each task of each iteration
    new Hook(function () {
        unlink('foo.txt');
    })
)
```

Passing some data to tasks
--------------------------

[](#passing-some-data-to-tasks)

As you can see from the above example, the same data is used across all tasks. Furthermore, we could need to generate random data at each iteration. But since mutability makes it really difficult for StreetFight to keep track on the data (and passing it into objects complicates the API), it has been decided to define it outside of StreetFight itself in a procedural way. So, here's how you would use arbitrary data, based on the previous example:

```
use StreetFight\Challenger\Challenger;
use StreetFight\Challenger\ChallengerList;
use StreetFight\Round\Round;
use StreetFight\Hook\Hook;

$data = [
    'filename' => 'foo.txt',
    'content' => 'bar'
];

new Round(
    new ChallengerList(
        new Challenger('file_put_contents (overwrite)', function () use ($data) {
            file_put_contents($data['filename'], $data['content']);
        }),
        new Challenger('fwrite (overwrite)', function () use ($data) {
            $f = fopen($data['filename'], 'w');
            fwrite($f, $data['content']);
            fclose($f);
        }),
        new Challenger('file_put_contents (append)', function () use ($data) {
            file_put_contents($data['filename'], $data['content'], FILE_APPEND);
        }),
        new Challenger('fwrite (append)', function () use ($data) {
            $f = fopen($data['filename'], 'a');
            fwrite($f, $data['content']);
            fclose($f);
        }),
    ),
    new Hook(function () {
        touch($data['filename']);
    }),
    new Hook(function () {
        unlink($data['filename']);
    })
)
```

Side note
---------

[](#side-note)

Depending on what code you're benchmarking, the execution time can exceed the `max_execution_time` directive of PHP. Just set `set_time_limit(0)` and you'll be all good.

License
-------

[](#license)

[MIT](http://dreamysource.mit-license.org).

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity4

Limited adoption so far

Community4

Small or concentrated contributor base

Maturity68

Established project with proven stability

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 ~32 days

Recently: every ~0 days

Total

24

Last Release

2457d ago

Major Versions

1.0.3 → 2.0.02017-08-18

2.0.0 → 3.0.02017-08-22

3.0.3 → 4.0.02017-08-24

4.1.0 → 5.0.02017-08-24

5.1.0 → 6.0.02019-08-19

PHP version history (2 changes)1.0.0PHP &gt;=7.1.0

6.0.0PHP &gt;=7.2.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/7f97d81cfd6d30587cdae24925bc0899331394d723d04ee4b76eb9435a565fe9?d=identicon)[pyrsmk](/maintainers/pyrsmk)

---

Tags

microbenchmark

### Embed Badge

![Health badge](/badges/pyrsmk-streetfight/health.svg)

```
[![Health](https://phpackages.com/badges/pyrsmk-streetfight/health.svg)](https://phpackages.com/packages/pyrsmk-streetfight)
```

###  Alternatives

[devster/ubench

Micro PHP library for benchmarking

5701.0M29](/packages/devster-ubench)[christophrumpel/artisan-benchmark

Benchmark Artisan Commands

17966.6k](/packages/christophrumpel-artisan-benchmark)[dragon-code/benchmark

Simple comparison of code execution speed between different options

11934.7k5](/packages/dragon-code-benchmark)[ayesh/php-timer

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

22226.4k11](/packages/ayesh-php-timer)

PHPackages © 2026

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