PHPackages                             firstrow/feature-science - 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. [Testing &amp; Quality](/categories/testing)
4. /
5. firstrow/feature-science

ActiveLibrary[Testing &amp; Quality](/categories/testing)

firstrow/feature-science
========================

A PHP 5.4 library to benchmark/refactroing big code changes and performance on production.

176PHP

Since Nov 13Pushed 11y ago1 watchersCompare

[ Source](https://github.com/firstrow/feature-science)[ Packagist](https://packagist.org/packages/firstrow/feature-science)[ RSS](/packages/firstrow-feature-science/feed)WikiDiscussions master Synced 3w ago

READMEChangelogDependenciesVersions (1)Used By (0)

FeatureScience!
===============

[](#featurescience)

[![Build Status](https://camo.githubusercontent.com/7cd057ee48ef6e72c72d59b21aff744a1cc97ea541c69a19fcd5612cdce0ccc5/68747470733a2f2f7472617669732d63692e6f72672f6669727374726f772f666561747572652d736369656e63652e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/firstrow/feature-science)

A PHP 5.4 library for refactoring, performance and issue testing new/old code in your production projects.

How to use it?
==============

[](#how-to-use-it)

For example, let's pretend you're changing caching backend. The following code example will help you to test and compare performance of new code under load.

```
$experiment = new \FeatureScience\Test('cacher.save', [
    'control'   => function() { $this->filecache->save() }, // old code
    'candidate' => function() { $this->memcached->save() }, // new code
]);

$experiment->run();
```

How does it work?
-----------------

[](#how-does-it-work)

`$experiment->run()` will randomly select one of the testing subjects from array, run it and return result. Behind the scenes `Test::run` will collect duration, memory usage, exceptions of both behaviors and save it to the `storage`.
To not load server by writing files each request, FeatureScience will store temporary data in APC storage and after experiment has been run 100 times, will save its results to the specified directory. You can change this limit by calling `$experiment->setPayloadLimit(number).`

Configuring
===========

[](#configuring)

By default `payload.saver` saves results into [system temp dir](http://ua1.php.net/sys_get_temp_dir). But you can configure your own path.

**Note:** Remember to make that path writable by the web server.

```
use FeatureScience\PayloadSaver;

\FeatureScience\DI::set('payload.saver', new PayloadSaver('/path/to/save/results'));
```

Viewing results
===============

[](#viewing-results)

You can view with your favorite editor or by typing command:

```
vendor/bin/feature-science /path/to/feature.name.json
```

It will look like:

```
{
    "name":"array.performance",
    "control":{
        "duration":0.01359,
        "exception":null
    },
    "candidate":{
        "duration":0.00261,
        "exception":{
            "message": "Ooops! Something went wrong",
            "code": "503",
            "file": "test.php",
            "line": "27"
        }
    }
}
```

Installation via Composer
=========================

[](#installation-via-composer)

Add FeatureScience to composer.json and run installation.

```
{
    "require": {
        "firstrow/feature-science": "dev-master"
    }
}
```

Overhead
========

[](#overhead)

Each benchmark runs test code 1000 times.

```
php benchmarks/clean.php       13.37s
php benchmarks/experiment.php  13.80s

```

So, its around +0.4s total execution time for each 1000 requests or 0.0004ms per one request.

Todo
----

[](#todo)

- Track memory usage
- Save min, avg, max duration

### Links

[](#links)

Inspired by ruby gem [dat-science](https://github.com/github/dat-science)
Also, you may find useful [athletic](https://github.com/polyfractal/athletic)

###  Health Score

22

—

LowBetter than 21% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity12

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 98.4% 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.

### Community

Maintainers

![](https://www.gravatar.com/avatar/08051b4f0215755c000901bb50d7eee65735881d44cb3260f785fd6d666428f8?d=identicon)[firstrow](/maintainers/firstrow)

---

Top Contributors

[![firstrow](https://avatars.githubusercontent.com/u/66944?v=4)](https://github.com/firstrow "firstrow (61 commits)")[![vasylchenko](https://avatars.githubusercontent.com/u/1675775?v=4)](https://github.com/vasylchenko "vasylchenko (1 commits)")

### Embed Badge

![Health badge](/badges/firstrow-feature-science/health.svg)

```
[![Health](https://phpackages.com/badges/firstrow-feature-science/health.svg)](https://phpackages.com/packages/firstrow-feature-science)
```

###  Alternatives

[dms/phpunit-arraysubset-asserts

This package provides ArraySubset and related asserts once deprecated in PHPUnit 8

14429.2M361](/packages/dms-phpunit-arraysubset-asserts)[gong023/assert_chain

enable you to use phpunit assert with method chain

1478.9k3](/packages/gong023-assert-chain)

PHPackages © 2026

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