Skip to content
This repository was archived by the owner on Jan 27, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,5 @@
#
# https://help.github.com/articles/ignoring-files/#create-a-global-gitignore

wip/
vendor/

composer.phar
/provider/*/vendor/
/vendor/
85 changes: 85 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
sudo: false
dist: trusty

language: php

php:
- 7.0
- 7.1
- 7.2
- nightly

matrix:
fast_finish: true
allow_failures:
- php: nightly

git:
depth: 1

env:
global:
- CC="ccache gcc"
- PHALCON_VERSION=v3.3.0
- PATH=/root/.composer/vendor/bin:$PATH
# TODO
- HAS_CACHING_METADATA_SUPPORT=0
matrix:
- PROVIDER=activerecord
- PROVIDER=cake
- PROVIDER=doctrine
- PROVIDER=eloquent
- PROVIDER=phalcon
- PROVIDER=propel
- PROVIDER=yii

cache:
# See: https://github.com/travis-ci/travis-ci/issues/8714
edge: true
apt: true
ccache: true
timeout: 604800
directories:
- .temp
- $HOME/.ccache
- $HOME/.composer/cache
- $HOME/pear
- $HOME/.cache/src
- $HOME/.local/lib

before_install:
- ulimit -c unlimited -S || true
- phpenv config-rm xdebug.ini || true
- if [[ ! -z "${GH_TOKEN}" ]]; then composer config github-oauth.github.com ${GH_TOKEN}; echo "Configured Github token"; fi;
- if [[ $PROVIDER == "phalcon" ]]; then bash $TRAVIS_BUILD_DIR/ci/install_phalcon.sh; fi;
- if [[ $PROVIDER == "yii" ]]; then composer global require --prefer-dist --no-interaction --no-suggest "fxp/composer-asset-plugin:~1.4"; fi;

install:
- (cd $TRAVIS_BUILD_DIR/provider/$PROVIDER; composer install --no-dev --no-interaction --prefer-dist --no-suggest --optimize-autoloader)
- (cd $TRAVIS_BUILD_DIR; composer install --no-dev --no-interaction --prefer-dist --no-suggest --optimize-autoloader)
- phpenv config-add $TRAVIS_BUILD_DIR/ci/benchmark.ini
- ls -al `$(phpenv which php-config) --extension-dir`
- $(phpenv which php) -v
- $(phpenv which php) -m
- echo 'SHOW VARIABLES LIKE "%version%"' | mysql -u root

before_script:
- echo 'CREATE DATABASE orm_benchmark CHARSET=utf8 COLLATE=utf8_unicode_ci' | mysql -u root
- echo "CREATE USER 'enigma'@'%' IDENTIFIED BY 'secret'" | mysql -u root
- echo "GRANT ALL PRIVILEGES ON orm_benchmark.* TO 'enigma'@'%' WITH GRANT OPTION" | mysql -u root
- cat schema/orm-benchmark.sql | mysql -u root orm_benchmark

script:
- cd $TRAVIS_BUILD_DIR
- php run $PROVIDER read 1
- php run $PROVIDER read 10
- php run $PROVIDER create 1
- php run $PROVIDER create 10
- if [[ $HAS_CACHING_METADATA_SUPPORT == 1 ]]; then php run $PROVIDER read 1 1; fi;
- if [[ $HAS_CACHING_METADATA_SUPPORT == 1 ]]; then php run $PROVIDER read 10 1; fi;

notifications:
# Stop spam me. I already live on Travis CI and GitHub
email:
on_success: never
on_failure: never
236 changes: 28 additions & 208 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,221 +1,42 @@
# PHP ORM Benchmark

The Docker based project to facilitate PHP ORM benchmarks.

## Contents <sup>[↑](#php-orm-benchmark)</sup>

* [Requirements](#requirements-)
* [ORMs to Benchmark](#orms-to-benchmark-)
* [Getting Started](#getting-started-)
* [Running Benchmark](#running-benchmark-)
* [Results](#results-)
* [Benchmarking Environment](#benchmarking-environment-)
* [First run](#first-run-)
* [Insert a record to the Database](#insert-a-record-to-the-database-)
* [Get first record with relation](#get-first-record-with-relation-)
* [10-fold method call](#10-fold-method-call-)
* [Insert a record to the Database](#insert-a-record-to-the-database--1)
* [Get first record with relation](#get-first-record-with-relation--1)
* [First run with metadata caching](#first-run-with-metadata-caching-)
* [Get first record with relation](#get-first-record-with-relation--2)
* [10-fold method call with metadata caching](#10-fold-method-call-with-metadata-caching-)
* [Get first record with relation](#get-first-record-with-relation--3)
* [Contributing](#contributing-)
* [Discussion](#discussion-)
* [References](#references-)
* [License](#license-)

## Requirements <sup>[↑](#php-orm-benchmark)</sup>

* Linux or BDS System
* Docker CE/EE >= 17.09.0
* Docker Compose >= 1.17
* PHP >= 7.0
* Composer

## ORMs to Benchmark <sup>[↑](#php-orm-benchmark)</sup>
# PHP ORM Benchmark [![Build Status](https://travis-ci.org/sergeyklay/php-orm-benchmark.svg?branch=master)](https://travis-ci.org/sergeyklay/php-orm-benchmark)

* Phalcon 3.3.0
* Propel ORM 2.0.0-alpha7
* Eloquent 5.5.28
* CakePHP ORM 3.5.10
* Yii ActiveRecord 2.0.13.1
* Doctrine ORM 2.5.14
* PHP ActiveRecord 1.2.0

## Getting Started <sup>[↑](#php-orm-benchmark)</sup>

First you have to build the benchmark application. Go to project root and run command as follows:

```sh
git clone git@github.com:sergeyklay/php-orm-benchmark.git
cd php-orm-benchmark
docker-compose build --force-rm --no-cache
```

I advise you to rely on [Composer](https://getcomposer.org) to manage projects’ dependencies.
You have to download and install Composer itself in a common location or in project root by executing in a terminal the command like this:

```sh
$ wget http://getcomposer.org/composer.phar
# If you haven't wget on your computer
$ curl -s http://getcomposer.org/installer | php
```

Then, to install all project's dependencies, type the following from the project root:

```sh
php composer.phar install
```

**Note:** You may skip Phalcon by running `php composer.phar install --ignore-platform-reqs`, if you don't have it installed at host system.

Finally, start the benchmark application:

```sh
docker-compose run benchmark
```

### Running Benchmark <sup>[↑](#php-orm-benchmark)</sup>

To run benchmark simple run command as follows:

```sh
php run <provider> <test>
```

Available providers are:

* `phalcon`
* `propel`
* `eloquent`
* `cake`
* `yii`
* `doctrine`
* `activerecord`

Available tests are:

* `create`
* `read`

To run benchmark multiple times use:
The benchmark to compare different ORM solutions for PHP.

```sh
php run <provider> <test> <times>
```
Initially this project used Docker to facilitate PHP ORM benchmarks. But after [repeated](https://github.com/sergeyklay/php-orm-benchmark/pull/12) [comments](https://github.com/sergeyklay/php-orm-benchmark/issues/7) I decided to transfer the benchmarks to [Travis CI](https://travis-ci.org/sergeyklay/php-orm-benchmark).

Some ORMs rely (depends) on models metadata caching. Thus, to avoid [controversy](https://github.com/sergeyklay/php-orm-benchmark/issues/4)
there is an ability to create and run test with metadata caching support. To use models metadata caching (if supports) you can use the
4th command line argument as follows:
So everyone [can see the results](https://travis-ci.org/sergeyklay/php-orm-benchmark) or run them again. Actually I've enabled the daily [cron job on Travis CI](https://docs.travis-ci.com/user/cron-jobs/).

```sh
php run <provider> <test> <times> 1
```
NOTE: Some ORMs rely (depends) on models metadata caching. Thus, to avoid [controversy](https://github.com/sergeyklay/php-orm-benchmark/issues/4) there is an ability to create and run test with metadata caching support.

To destroy the application use the following command from the host system:
## ORMs to Benchmark

```sh
docker-compose down
docker volume rm phpormbenchmark_mysql
```

## Results <sup>[↑](#php-orm-benchmark)</sup>

These are my benchmarks, not yours. **I encourage you to run on your (production equivalent) environments.**
By sharing underlying software stacks, the benchmark results vary only according to the host machine's hardware specs and differing code implementations.

### Benchmarking Environment <sup>[↑](#php-orm-benchmark)</sup>

* Debian GNU/Linux 8.10 (jessie) 64bit (Docker)
* PHP 7.0.26
* Zend OPcache 7.0.26
* MySQL 5.7

### First run <sup>[↑](#php-orm-benchmark)</sup>

#### Insert a record to the Database <sup>[↑](#php-orm-benchmark)</sup>

| ORM | Elapsed time (ms) | Used memory (KiB) | Total memory usage (KiB) | Method |
|-------------------|--------------------:|------------------:|-------------------------:|--------------|
| Doctrine | 180.52 | 764.05 | 1,992,804.41 | `flush` |
| CakePHP | 288.97 | 836.86 | 1,546,380.41 | `save` |
| Eloquent | 130.20 | 520.95 | 1,530,852.41 | `save` |
| Propel | 101.60 | 278.77 | 977,372.41 | `save` |
| Yii | 40.72 | 225.01 | 1,180,652.41 | `save` |
| PHP ActiveRecord | 28.12 | 118.91 | 804,852.41 | `save` |
| Phalcon | 9.13 | 32.66 | 720,812.41 | `save` |

#### Get first record with relation <sup>[↑](#php-orm-benchmark)</sup>

| ORM | Elapsed time (ms) | Used memory (KiB) | Total memory usage (KiB) | Method |
|-------------------|--------------------:|------------------:|-------------------------:|--------------|
| Doctrine | 202.51 | 798.64 | 2,028,596.41 | `findOneBy` |
| CakePHP | 282.98 | 977.05 | 1,690,308.41 | `find` |
| Eloquent | 127.85 | 559.12 | 1,570,316.41 | `firstOrFail`|
| Propel | 154.12 | 725.33 | 1,435,020.41 | `findPk` |
| Yii | 69.66 | 325.98 | 1,284,428.41 | `findOne` |
| PHP ActiveRecord | 28.19 | 57.23 | 742,100.41 | `first` |
| Phalcon | 10.79 | 67.12 | 756,092.41 | `findFirst` |

### 10-fold method call <sup>[↑](#php-orm-benchmark)</sup>

#### Insert a record to the Database <sup>[↑](#php-orm-benchmark)</sup>

| ORM | Elapsed time (ms) | Used memory (KiB) | Total memory usage (KiB) | Method |
|-------------------|--------------------:|------------------:|-------------------------:|--------------|
| Doctrine | 19.36 | 78.26 | 2,011,436.41 | `flush` |
| CakePHP | 24.61 | 83.72 | 1,546,380.41 | `save` |
| Eloquent | 14.80 | 52.13 | 1,530,852.41 | `save` |
| Propel | 9.05 | 28.16 | 979,996.41 | `save` |
| Yii | 5.46 | 23.94 | 1,195,028.41 | `save` |
| PHP ActiveRecord | 4.98 | 11.95 | 804,852.41 | `save` |
| Phalcon | 2.13 | 3.33 | 721,420.41 | `save` |

#### Get first record with relation <sup>[↑](#php-orm-benchmark)</sup>

| ORM | Elapsed time (ms) | Used memory (KiB) | Total memory usage (KiB) | Method |
|-------------------|--------------------:|------------------:|-------------------------:|--------------|
| Doctrine | 18.96 | 83.29 | 2,063,724.41 | `findOneBy` |
| CakePHP | 29.33 | 97.70 | 1,690,308.41 | `find` |
| Eloquent | 13.55 | 55.91 | 1,570,316.41 | `firstOrFail`|
| Propel | 15.44 | 73.15 | 1,441,348.41 | `findPk` |
| Yii | 8.03 | 35.40 | 1,313,084.41 | `findOne` |
| PHP ActiveRecord | 2.95 | 5.72 | 742,100.41 | `first` |
| Phalcon | 1.54 | 15.54 | 846,444.41 | `findFirst` |

### First run with metadata caching <sup>[↑](#php-orm-benchmark)</sup>

#### Get first record with relation <sup>[↑](#php-orm-benchmark)</sup>

| ORM | Elapsed time (ms) | Used memory (KiB) | Total memory usage (KiB) | MetaData Storage |
|-------------------|--------------------:|------------------:|-------------------------:|------------------|
| Doctrine | 145.61 | 264.44 | 2,033,836.41 | File System |
| CakePHP | 273.66 | 1,075.52 | 1,793,772.41 | File System |
| Phalcon | 18.69 | 60.75 | 750,268.41 | File System |

### 10-fold method call with metadata caching <sup>[↑](#php-orm-benchmark)</sup>
* CakePHP ORM 3.5.10
* Doctrine ORM 2.5.14
* Eloquent 5.5.28
* PHP ActiveRecord 1.2.0
* Phalcon 3.3.0
* Propel ORM 2.0.0-alpha7
* Yii ActiveRecord 2.0.13.1

#### Get first record with relation <sup>[↑](#php-orm-benchmark)</sup>
## Benchmarking Environment

| ORM | Elapsed time (ms) | Used memory (KiB) | Total memory usage (KiB) | MetaData Storage |
|-------------------|--------------------:|------------------:|-------------------------:|------------------|
| Doctrine | 15.65 | 29.87 | 2,068,964.41 | File System |
| CakePHP | 30.18 | 107.55 | 1,793,772.41 | File System |
| Phalcon | 2.27 | 14.90 | 840,620.41 | File System |
* Ubuntu 14.04.5 (Trusty) 64bit (Travis CI)
* PHP 7.0, 7.1, 7.2, 7.3
* Zend OPcache 7.0, 7.1, 7.2, 7.3
* MySQL 5.6

## Contributing <sup>[↑](#php-orm-benchmark)</sup>
## What we test

The source for this extension is available on [GitHub](https://github.com/sergeyklay/php-orm-benchmark). If anyone feels that there is
something missing or would like to suggest improvements please [open a new issue](https://github.com/sergeyklay/php-orm-benchmark/issues)
or send a pull request.
* Insert a record to the Database
* Get first record with relation
* Insert a record to the Database (10-fold method call)
* Get first record with relation (10-fold method call)

## Discussion <sup>[↑](#php-orm-benchmark)</sup>
## Contributing

There is an `#general` channel on the Phalcon [Discord Server](https://discord.gg/PNFsSsr).
If you would like to discuss an idea or need help or have other feedback you can usually find me (`@klay`) idling there.
Contributions for new ORMs are more than welcome! If anyone feels that there is something missing or would like to suggest improvements please [open a new issue](https://github.com/sergeyklay/php-orm-benchmark/issues) or send a pull request.

## References <sup>[↑](#php-orm-benchmark)</sup>
## References

* [Eloquent ORM](https://laravel.com/docs/5.5/eloquent)
* [Phalcon ORM](https://docs.phalconphp.com/en/3.2/db-models)
Expand All @@ -225,10 +46,9 @@ If you would like to discuss an idea or need help or have other feedback you can
* [Doctrine ORM](http://www.doctrine-project.org/projects/orm.html)
* [PHP ActiveRecord](http://www.phpactiverecord.org/projects/main/wiki)

## License <sup>[↑](#php-orm-benchmark)</sup>
## License

The "PHP ORM Benchmark" is open source software licensed under the MIT License.
See the [LICENSE](https://github.com/sergeyklay/php-orm-benchmark/blob/master/LICENSE) file for more.
The "PHP ORM Benchmark" is open source software licensed under the MIT License. See the [LICENSE](https://github.com/sergeyklay/php-orm-benchmark/blob/master/LICENSE) file for more.

---

Expand Down
File renamed without changes.
Loading