1
0
mirror of synced 2025-02-09 08:49:26 +03:00

Merge pull request #6575 from lcobucci/improvement/move-performance-tests-to-phpbench

Move performance tests to phpbench
This commit is contained in:
Luís Cobucci 2017-07-23 10:46:26 +02:00 committed by GitHub
commit 84079572f7
30 changed files with 1595 additions and 951 deletions

1
.gitignore vendored
View File

@ -12,3 +12,4 @@ lib/Doctrine/DBAL
.idea
vendor/
composer.lock
/tests/Doctrine/Performance/history.db

View File

@ -22,11 +22,13 @@ before_script:
- if [[ $PHPSTAN = 1 ]]; then composer require --dev --prefer-stable phpstan/phpstan:^0.7 symfony/console:^3.0; fi
- if [ "$MYSQL_VERSION" == "5.7" ]; then bash ./tests/travis/install-mysql-5.7.sh; fi;
- if [[ $DB == "mysql" || $DB == "mariadb" ]]; then mysql -e "CREATE SCHEMA doctrine_tests; GRANT ALL PRIVILEGES ON doctrine_tests.* to travis@'%'"; fi;
- if [[ $PHPBENCH = 1 ]]; then wget https://phpbench.github.io/phpbench/phpbench.phar https://phpbench.github.io/phpbench/phpbench.phar.pubkey; fi
script:
- if [[ $PHPSTAN = 1 ]]; then vendor/bin/phpstan analyse -l 1 -c phpstan.neon lib; fi
- ENABLE_SECOND_LEVEL_CACHE=0 ./vendor/bin/phpunit -v -c tests/travis/$DB.travis.xml $PHPUNIT_FLAGS
- ENABLE_SECOND_LEVEL_CACHE=1 ./vendor/bin/phpunit -v -c tests/travis/$DB.travis.xml --exclude-group performance,non-cacheable,locking_functional
- if [[ $PHPBENCH = 1 ]]; then php phpbench.phar run -l dots --report=default; fi
- if [[ $DB != "none" ]]; then ENABLE_SECOND_LEVEL_CACHE=0 ./vendor/bin/phpunit -v -c tests/travis/$DB.travis.xml $PHPUNIT_FLAGS; fi
- if [[ $DB != "none" ]]; then ENABLE_SECOND_LEVEL_CACHE=1 ./vendor/bin/phpunit -v -c tests/travis/$DB.travis.xml --exclude-group performance,non-cacheable,locking_functional; fi
after_script:
- if [[ "$PHPUNIT_FLAGS" != "" ]]; then wget https://scrutinizer-ci.com/ocular.phar; fi
@ -39,14 +41,15 @@ matrix:
env: DB=mariadb
addons:
mariadb: 10.1
- php: 7.1
env:
- DB=sqlite
- DEPENDENCIES='low'
- php: 7.1
env:
- DB=pgsql
- PHPSTAN=1
- php: 7.1
env: DB=mysql MYSQL_VERSION=5.7
@ -55,6 +58,15 @@ matrix:
env: DB=mysql MYSQL_VERSION=5.7
sudo: required
- php: 7.1
env:
- DB=none
- PHPSTAN=1
- php: 7.1
env:
- DB=none
- PHPBENCH=1
allow_failures:
- php: nightly

View File

@ -35,7 +35,10 @@
"psr-4": { "Doctrine\\ORM\\": "lib/Doctrine/ORM" }
},
"autoload-dev": {
"psr-4": { "Doctrine\\Tests\\": "tests/Doctrine/Tests" }
"psr-4": {
"Doctrine\\Tests\\": "tests/Doctrine/Tests",
"Doctrine\\Performance\\": "tests/Doctrine/Performance"
}
},
"bin": ["bin/doctrine"],
"extra": {

15
phpbench.json Normal file
View File

@ -0,0 +1,15 @@
{
"bootstrap": "vendor/autoload.php",
"path": "tests/Doctrine/Performance",
"extensions": [
"PhpBench\\Extensions\\Dbal\\DbalExtension",
"PhpBench\\Extensions\\XDebug\\XDebugExtension"
],
"storage": "dbal",
"storage.dbal.connection": {
"driver": "pdo_sqlite",
"path": "tests/Doctrine/Performance/history.db"
}
}

View File

@ -0,0 +1,73 @@
<?php
namespace Doctrine\Performance\ChangeSet;
use Doctrine\ORM\Query;
use Doctrine\ORM\UnitOfWork;
use Doctrine\Performance\EntityManagerFactory;
use Doctrine\Tests\Mocks\HydratorMockStatement;
use Doctrine\Tests\Models\CMS\CmsUser;
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
/**
* @BeforeMethods({"init"})
*/
final class UnitOfWorkComputeChangesBench
{
/**
* @var CmsUser[]
*/
private $users;
/**
* @var UnitOfWork
*/
private $unitOfWork;
public function init()
{
$this->unitOfWork = EntityManagerFactory::getEntityManager([])->getUnitOfWork();
for ($i = 1; $i <= 100; ++$i) {
$user = new CmsUser;
$user->id = $i;
$user->status = 'user';
$user->username = 'user' . $i;
$user->name = 'Mr.Smith-' . $i;
$this->users[] = $user;
$this->unitOfWork->registerManaged(
$user,
[
'id' => $i,
],
[
'id' => $user->id,
'status' => $user->status,
'username' => $user->username,
'name' => $user->name,
'address' => $user->address,
'email' => $user->email,
]
);
}
$this->unitOfWork->computeChangeSets();
if ($this->unitOfWork->getScheduledEntityUpdates()) {
throw new \LogicException('Unit of work should be clean at this stage');
}
foreach ($this->users AS $user) {
$user->status = 'other';
$user->username .= '++';
$user->name = str_replace('Mr.', 'Mrs.', $user->name);
}
}
public function benchChangeSetComputation()
{
$this->unitOfWork->computeChangeSets();
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace Doctrine\Performance;
use Doctrine\DBAL\Driver\PDOSqlite\Driver;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Proxy\ProxyFactory;
use Doctrine\ORM\Tools\SchemaTool;
final class EntityManagerFactory
{
public static function getEntityManager(array $schemaClassNames) : EntityManagerInterface
{
$config = new Configuration();
$config->setProxyDir(__DIR__ . '/../Tests/Proxies');
$config->setProxyNamespace('Doctrine\Tests\Proxies');
$config->setAutoGenerateProxyClasses(ProxyFactory::AUTOGENERATE_EVAL);
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver([
realpath(__DIR__ . '/Models/Cache'),
realpath(__DIR__ . '/Models/GeoNames')
], true));
$entityManager = EntityManager::create(
[
'driverClass' => Driver::class,
'memory' => true,
],
$config
);
(new SchemaTool($entityManager))
->createSchema(array_map([$entityManager, 'getClassMetadata'], $schemaClassNames));
return $entityManager;
}
}

View File

@ -0,0 +1,92 @@
<?php
namespace Doctrine\Performance\Hydration;
use Doctrine\ORM\Internal\Hydration\ArrayHydrator;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Performance\EntityManagerFactory;
use Doctrine\Tests\Mocks\HydratorMockStatement;
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
use Doctrine\Tests\Models\CMS\CmsUser;
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
/**
* @BeforeMethods({"init"})
*/
final class MixedQueryFetchJoinArrayHydrationPerformanceBench
{
/**
* @var ArrayHydrator
*/
private $hydrator;
/**
* @var ResultSetMapping
*/
private $rsm;
/**
* @var HydratorMockStatement
*/
private $stmt;
public function init()
{
$resultSet = [
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'sclr0' => 'ROMANB',
'p__phonenumber' => '42',
],
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'sclr0' => 'ROMANB',
'p__phonenumber' => '43',
],
[
'u__id' => '2',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'sclr0' => 'JWAGE',
'p__phonenumber' => '91'
]
];
for ($i = 4; $i < 10000; ++$i) {
$resultSet[] = [
'u__id' => $i,
'u__status' => 'developer',
'u__username' => 'jwage',
'u__name' => 'Jonathan',
'sclr0' => 'JWAGE' . $i,
'p__phonenumber' => '91'
];
}
$this->stmt = new HydratorMockStatement($resultSet);
$this->hydrator = new ArrayHydrator(EntityManagerFactory::getEntityManager([]));
$this->rsm = new ResultSetMapping;
$this->rsm->addEntityResult(CmsUser::class, 'u');
$this->rsm->addJoinedEntityResult(CmsPhonenumber::class, 'p', 'u', 'phonenumbers');
$this->rsm->addFieldResult('u', 'u__id', 'id');
$this->rsm->addFieldResult('u', 'u__status', 'status');
$this->rsm->addFieldResult('u', 'u__username', 'username');
$this->rsm->addFieldResult('u', 'u__name', 'name');
$this->rsm->addScalarResult('sclr0', 'nameUpper');
$this->rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
}
public function benchHydration()
{
$this->hydrator->hydrateAll($this->stmt, $this->rsm);
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace Doctrine\Performance\Hydration;
use Doctrine\ORM\Internal\Hydration\ObjectHydrator;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Performance\EntityManagerFactory;
use Doctrine\Tests\Mocks\HydratorMockStatement;
use Doctrine\Tests\Models\CMS\CmsAddress;
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
use Doctrine\Tests\Models\CMS\CmsUser;
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
/**
* @BeforeMethods({"init"})
*/
final class MixedQueryFetchJoinFullObjectHydrationPerformanceBench
{
/**
* @var ObjectHydrator
*/
private $hydrator;
/**
* @var ResultSetMapping
*/
private $rsm;
/**
* @var HydratorMockStatement
*/
private $stmt;
public function init()
{
$resultSet = [
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'sclr0' => 'ROMANB',
'p__phonenumber' => '42',
'a__id' => '1'
]
];
for ($i = 2; $i < 2000; ++$i) {
$resultSet[] = [
'u__id' => $i,
'u__status' => 'developer',
'u__username' => 'jwage',
'u__name' => 'Jonathan',
'sclr0' => 'JWAGE' . $i,
'p__phonenumber' => '91',
'a__id' => $i
];
}
$this->stmt = new HydratorMockStatement($resultSet);
$this->hydrator = new ObjectHydrator(EntityManagerFactory::getEntityManager([]));
$this->rsm = new ResultSetMapping;
$this->rsm->addEntityResult(CmsUser::class, 'u');
$this->rsm->addJoinedEntityResult(CmsPhonenumber::class, 'p', 'u', 'phonenumbers');
$this->rsm->addFieldResult('u', 'u__id', 'id');
$this->rsm->addFieldResult('u', 'u__status', 'status');
$this->rsm->addFieldResult('u', 'u__username', 'username');
$this->rsm->addFieldResult('u', 'u__name', 'name');
$this->rsm->addScalarResult('sclr0', 'nameUpper');
$this->rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
$this->rsm->addJoinedEntityResult(CmsAddress::class, 'a', 'u', 'address');
$this->rsm->addFieldResult('a', 'a__id', 'id');
}
public function benchHydration()
{
$this->hydrator->hydrateAll($this->stmt, $this->rsm);
}
}

View File

@ -0,0 +1,93 @@
<?php
namespace Doctrine\Performance\Hydration;
use Doctrine\ORM\Internal\Hydration\ObjectHydrator;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Performance\EntityManagerFactory;
use Doctrine\Tests\Mocks\HydratorMockStatement;
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
use Doctrine\Tests\Models\CMS\CmsUser;
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
/**
* @BeforeMethods({"init"})
*/
final class MixedQueryFetchJoinPartialObjectHydrationPerformanceBench
{
/**
* @var ObjectHydrator
*/
private $hydrator;
/**
* @var ResultSetMapping
*/
private $rsm;
/**
* @var HydratorMockStatement
*/
private $stmt;
public function init()
{
$resultSet = [
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'sclr0' => 'ROMANB',
'p__phonenumber' => '42',
],
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'sclr0' => 'ROMANB',
'p__phonenumber' => '43',
],
[
'u__id' => '2',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'sclr0' => 'JWAGE',
'p__phonenumber' => '91'
]
];
for ($i = 4; $i < 2000; ++$i) {
$resultSet[] = [
'u__id' => $i,
'u__status' => 'developer',
'u__username' => 'jwage',
'u__name' => 'Jonathan',
'sclr0' => 'JWAGE' . $i,
'p__phonenumber' => '91'
];
}
$this->stmt = new HydratorMockStatement($resultSet);
$this->hydrator = new ObjectHydrator(EntityManagerFactory::getEntityManager([]));
$this->rsm = new ResultSetMapping;
$this->rsm->addEntityResult(CmsUser::class, 'u');
$this->rsm->addJoinedEntityResult(CmsPhonenumber::class, 'p', 'u', 'phonenumbers');
$this->rsm->addFieldResult('u', 'u__id', 'id');
$this->rsm->addFieldResult('u', 'u__status', 'status');
$this->rsm->addFieldResult('u', 'u__username', 'username');
$this->rsm->addFieldResult('u', 'u__name', 'name');
$this->rsm->addScalarResult('sclr0', 'nameUpper');
$this->rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
}
public function benchHydration()
{
$this->hydrator->hydrateAll($this->stmt, $this->rsm, [Query::HINT_FORCE_PARTIAL_LOAD => true]);
}
}

View File

@ -0,0 +1,58 @@
<?php
namespace Doctrine\Performance\Hydration;
use Doctrine\Common\Persistence\ObjectRepository;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Performance\EntityManagerFactory;
use Doctrine\Tests\Models\CMS;
/**
* @BeforeMethods({"init"})
*/
final class SimpleHydrationBench
{
/**
* @var EntityManagerInterface
*/
private $entityManager;
/**
* @var ObjectRepository
*/
private $repository;
public function init()
{
$this->entityManager = EntityManagerFactory::getEntityManager([
CMS\CmsUser::class,
CMS\CmsPhonenumber::class,
CMS\CmsAddress::class,
CMS\CmsEmail::class,
CMS\CmsGroup::class,
CMS\CmsTag::class,
CMS\CmsArticle::class,
CMS\CmsComment::class,
]);
for ($i = 2; $i < 10000; ++$i) {
$user = new CMS\CmsUser();
$user->status = 'developer';
$user->username = 'jwage' . $i;
$user->name = 'Jonathan';
$this->entityManager->persist($user);
}
$this->entityManager->flush();
$this->entityManager->clear();
$this->repository = $this->entityManager->getRepository(CMS\CmsUser::class);
}
public function benchHydration()
{
$this->repository->findAll();
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace Doctrine\Performance\Hydration;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use Doctrine\Performance\EntityManagerFactory;
use Doctrine\Tests\Mocks\HydratorMockStatement;
use Doctrine\Tests\Models\CMS;
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
/**
* @BeforeMethods({"init"})
*/
final class SimpleInsertPerformanceBench
{
/**
* @var EntityManagerInterface
*/
private $entityManager;
/**
* @var CMS\CmsUser[]
*/
private $users;
public function init()
{
$this->entityManager = EntityManagerFactory::getEntityManager([
CMS\CmsUser::class,
CMS\CmsPhonenumber::class,
CMS\CmsAddress::class,
CMS\CmsEmail::class,
CMS\CmsGroup::class,
CMS\CmsTag::class,
CMS\CmsArticle::class,
CMS\CmsComment::class,
]);
for ($i = 1; $i <= 10000; ++$i) {
$user = new CMS\CmsUser;
$user->status = 'user';
$user->username = 'user' . $i;
$user->name = 'Mr.Smith-' . $i;
$this->users[$i] = $user;
}
}
public function benchHydration()
{
foreach ($this->users as $key => $user) {
$this->entityManager->persist($user);
if (! ($key % 20)) {
$this->entityManager->flush();
$this->entityManager->clear();
}
}
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace Doctrine\Performance\Hydration;
use Doctrine\ORM\Internal\Hydration\ArrayHydrator;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Performance\EntityManagerFactory;
use Doctrine\Tests\Mocks\HydratorMockStatement;
use Doctrine\Tests\Models\CMS\CmsUser;
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
/**
* @BeforeMethods({"init"})
*/
final class SimpleQueryArrayHydrationPerformanceBench
{
/**
* @var ArrayHydrator
*/
private $hydrator;
/**
* @var ResultSetMapping
*/
private $rsm;
/**
* @var HydratorMockStatement
*/
private $stmt;
public function init()
{
$resultSet = [
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
],
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
],
[
'u__id' => '2',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
]
];
for ($i = 4; $i < 10000; ++$i) {
$resultSet[] = [
'u__id' => $i,
'u__status' => 'developer',
'u__username' => 'jwage',
'u__name' => 'Jonathan',
];
}
$this->stmt = new HydratorMockStatement($resultSet);
$this->hydrator = new ArrayHydrator(EntityManagerFactory::getEntityManager([]));
$this->rsm = new ResultSetMapping;
$this->rsm->addEntityResult(CmsUser::class, 'u');
$this->rsm->addFieldResult('u', 'u__id', 'id');
$this->rsm->addFieldResult('u', 'u__status', 'status');
$this->rsm->addFieldResult('u', 'u__username', 'username');
$this->rsm->addFieldResult('u', 'u__name', 'name');
}
public function benchHydration()
{
$this->hydrator->hydrateAll($this->stmt, $this->rsm);
}
}

View File

@ -0,0 +1,74 @@
<?php
namespace Doctrine\Performance\Hydration;
use Doctrine\ORM\Internal\Hydration\ObjectHydrator;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Performance\EntityManagerFactory;
use Doctrine\Tests\Mocks\HydratorMockStatement;
use Doctrine\Tests\Models\CMS\CmsAddress;
use Doctrine\Tests\Models\CMS\CmsUser;
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
/**
* @BeforeMethods({"init"})
*/
final class SimpleQueryFullObjectHydrationPerformanceBench
{
/**
* @var ObjectHydrator
*/
private $hydrator;
/**
* @var ResultSetMapping
*/
private $rsm;
/**
* @var HydratorMockStatement
*/
private $stmt;
public function init()
{
$resultSet = [
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'a__id' => '1'
]
];
for ($i = 2; $i < 10000; ++$i) {
$resultSet[] = [
'u__id' => $i,
'u__status' => 'developer',
'u__username' => 'jwage',
'u__name' => 'Jonathan',
'a__id' => $i
];
}
$this->stmt = new HydratorMockStatement($resultSet);
$this->hydrator = new ObjectHydrator(EntityManagerFactory::getEntityManager([]));
$this->rsm = new ResultSetMapping;
$this->rsm->addEntityResult(CmsUser::class, 'u');
$this->rsm->addFieldResult('u', 'u__id', 'id');
$this->rsm->addFieldResult('u', 'u__status', 'status');
$this->rsm->addFieldResult('u', 'u__username', 'username');
$this->rsm->addFieldResult('u', 'u__name', 'name');
$this->rsm->addJoinedEntityResult(CmsAddress::class, 'a', 'u', 'address');
$this->rsm->addFieldResult('a', 'a__id', 'id');
}
public function benchHydration()
{
$this->hydrator->hydrateAll($this->stmt, $this->rsm);
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace Doctrine\Performance\Hydration;
use Doctrine\ORM\Internal\Hydration\ObjectHydrator;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Performance\EntityManagerFactory;
use Doctrine\Tests\Mocks\HydratorMockStatement;
use Doctrine\Tests\Models\CMS\CmsUser;
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
/**
* @BeforeMethods({"init"})
*/
final class SimpleQueryPartialObjectHydrationPerformanceBench
{
/**
* @var ObjectHydrator
*/
private $hydrator;
/**
* @var ResultSetMapping
*/
private $rsm;
/**
* @var HydratorMockStatement
*/
private $stmt;
public function init()
{
$resultSet = [
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
],
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
],
[
'u__id' => '2',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
]
];
for ($i = 4; $i < 10000; ++$i) {
$resultSet[] = [
'u__id' => $i,
'u__status' => 'developer',
'u__username' => 'jwage',
'u__name' => 'Jonathan',
];
}
$this->stmt = new HydratorMockStatement($resultSet);
$this->hydrator = new ObjectHydrator(EntityManagerFactory::getEntityManager([]));
$this->rsm = new ResultSetMapping;
$this->rsm->addEntityResult(CmsUser::class, 'u');
$this->rsm->addFieldResult('u', 'u__id', 'id');
$this->rsm->addFieldResult('u', 'u__status', 'status');
$this->rsm->addFieldResult('u', 'u__username', 'username');
$this->rsm->addFieldResult('u', 'u__name', 'name');
}
public function benchHydration()
{
$this->hydrator->hydrateAll($this->stmt, $this->rsm, [Query::HINT_FORCE_PARTIAL_LOAD => true]);
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace Doctrine\Performance\Hydration;
use Doctrine\ORM\Internal\Hydration\ScalarHydrator;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Performance\EntityManagerFactory;
use Doctrine\Tests\Mocks\HydratorMockStatement;
use Doctrine\Tests\Models\CMS\CmsUser;
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
/**
* @BeforeMethods({"init"})
*/
final class SimpleQueryScalarHydrationPerformanceBench
{
/**
* @var ScalarHydrator
*/
private $hydrator;
/**
* @var ResultSetMapping
*/
private $rsm;
/**
* @var HydratorMockStatement
*/
private $stmt;
public function init()
{
$resultSet = [
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
],
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
],
[
'u__id' => '2',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
]
];
for ($i = 4; $i < 10000; ++$i) {
$resultSet[] = [
'u__id' => $i,
'u__status' => 'developer',
'u__username' => 'jwage',
'u__name' => 'Jonathan',
];
}
$this->stmt = new HydratorMockStatement($resultSet);
$this->hydrator = new ScalarHydrator(EntityManagerFactory::getEntityManager([]));
$this->rsm = new ResultSetMapping;
$this->rsm->addEntityResult(CmsUser::class, 'u');
$this->rsm->addFieldResult('u', 'u__id', 'id');
$this->rsm->addFieldResult('u', 'u__status', 'status');
$this->rsm->addFieldResult('u', 'u__username', 'username');
$this->rsm->addFieldResult('u', 'u__name', 'name');
}
public function benchHydration()
{
$this->hydrator->hydrateAll($this->stmt, $this->rsm);
}
}

View File

@ -0,0 +1,107 @@
<?php
namespace Doctrine\Performance\Hydration;
use Doctrine\Common\Persistence\ObjectRepository;
use Doctrine\Performance\EntityManagerFactory;
use Doctrine\Tests\Models\Company;
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
/**
* @BeforeMethods({"init"})
*/
final class SingleTableInheritanceHydrationPerformanceBench
{
/**
* @var ObjectRepository
*/
private $contractsRepository;
/**
* @var ObjectRepository
*/
private $fixContractsRepository;
/**
* @var ObjectRepository
*/
private $flexContractRepository;
/**
* @var ObjectRepository
*/
private $ultraContractRepository;
public function init()
{
$entityManager = EntityManagerFactory::getEntityManager([
Company\CompanyPerson::class,
Company\CompanyEmployee::class,
Company\CompanyManager::class,
Company\CompanyOrganization::class,
Company\CompanyEvent::class,
Company\CompanyAuction::class,
Company\CompanyRaffle::class,
Company\CompanyCar::class,
Company\CompanyContract::class,
]);
$this->contractsRepository = $entityManager->getRepository(Company\CompanyContract::class);
$this->fixContractsRepository = $entityManager->getRepository(Company\CompanyFixContract::class);
$this->flexContractRepository = $entityManager->getRepository(Company\CompanyFlexContract::class);
$this->ultraContractRepository = $entityManager->getRepository(Company\CompanyFlexUltraContract::class);
$person = new Company\CompanyEmployee();
$person->setName('Poor Sales Guy');
$person->setDepartment('Sales');
$person->setSalary(100);
$entityManager->persist($person);
for ($i = 0; $i < 33; $i++) {
$fixContract = new Company\CompanyFixContract();
$flexContract = new Company\CompanyFlexContract();
$ultraContract = new Company\CompanyFlexUltraContract();
$fixContract->setFixPrice(1000);
$fixContract->setSalesPerson($person);
$fixContract->markCompleted();
$flexContract->setSalesPerson($person);
$flexContract->setHoursWorked(100);
$flexContract->setPricePerHour(100);
$flexContract->markCompleted();
$ultraContract->setSalesPerson($person);
$ultraContract->setHoursWorked(150);
$ultraContract->setPricePerHour(150);
$ultraContract->setMaxPrice(7000);
$entityManager->persist($fixContract);
$entityManager->persist($flexContract);
$entityManager->persist($ultraContract);
}
$entityManager->flush();
$entityManager->clear();
}
public function benchHydrateFixContracts()
{
$this->fixContractsRepository->findAll();
}
public function benchHydrateFlexContracts()
{
$this->flexContractRepository->findAll();
}
public function benchHydrateUltraContracts()
{
$this->ultraContractRepository->findAll();
}
public function benchHydrateAllContracts()
{
$this->contractsRepository->findAll();
}
}

View File

@ -0,0 +1,100 @@
<?php
namespace Doctrine\Performance\Hydration;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Performance\EntityManagerFactory;
use Doctrine\Tests\Models\Company;
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
/**
* @BeforeMethods({"init"})
*/
final class SingleTableInheritanceInsertPerformanceBench
{
/**
* @var EntityManagerInterface
*/
private $entityManager;
/**
* @var Company\CompanyFixContract[]
*/
private $fixContracts = [];
/**
* @var Company\CompanyFlexContract[]
*/
private $flexContracts = [];
/**
* @var Company\CompanyFlexUltraContract[]
*/
private $ultraContracts = [];
public function init()
{
$this->entityManager = EntityManagerFactory::getEntityManager([
Company\CompanyPerson::class,
Company\CompanyEmployee::class,
Company\CompanyManager::class,
Company\CompanyOrganization::class,
Company\CompanyEvent::class,
Company\CompanyAuction::class,
Company\CompanyRaffle::class,
Company\CompanyCar::class,
Company\CompanyContract::class,
]);
$person = new Company\CompanyEmployee();
$person->setName('Poor Sales Guy');
$person->setDepartment('Sales');
$person->setSalary(100);
$this->entityManager->persist($person);
for ($i = 0; $i < 33; $i++) {
$this->fixContracts[$i] = new Company\CompanyFixContract();
$this->fixContracts[$i]->setFixPrice(1000);
$this->fixContracts[$i]->setSalesPerson($person);
$this->fixContracts[$i]->markCompleted();
$this->flexContracts[$i] = new Company\CompanyFlexContract();
$this->flexContracts[$i]->setSalesPerson($person);
$this->flexContracts[$i]->setHoursWorked(100);
$this->flexContracts[$i]->setPricePerHour(100);
$this->flexContracts[$i]->markCompleted();
$this->ultraContracts[$i] = new Company\CompanyFlexUltraContract();
$this->ultraContracts[$i]->setSalesPerson($person);
$this->ultraContracts[$i]->setHoursWorked(150);
$this->ultraContracts[$i]->setPricePerHour(150);
$this->ultraContracts[$i]->setMaxPrice(7000);
}
}
public function benchInsertFixContracts()
{
array_map([$this->entityManager, 'persist'], $this->fixContracts);
$this->entityManager->flush();
}
public function benchInsertFlexContracts()
{
array_map([$this->entityManager, 'persist'], $this->flexContracts);
$this->entityManager->flush();
}
public function benchInsertUltraContracts()
{
array_map([$this->entityManager, 'persist'], $this->ultraContracts);
$this->entityManager->flush();
}
public function benchInsertAllContracts()
{
array_map([$this->entityManager, 'persist'], $this->fixContracts);
array_map([$this->entityManager, 'persist'], $this->flexContracts);
array_map([$this->entityManager, 'persist'], $this->ultraContracts);
$this->entityManager->flush();
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace Doctrine\Performance\LazyLoading;
use Doctrine\ORM\Proxy\Proxy;
use Doctrine\Performance\EntityManagerFactory;
use Doctrine\Performance\Mock\NonProxyLoadingEntityManager;
use Doctrine\Tests\Models\CMS\CmsEmployee;
use Doctrine\Tests\Models\CMS\CmsUser;
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
/**
* @BeforeMethods({"init"})
*/
final class ProxyInitializationTimeBench
{
/**
* @var Proxy[]
*/
private $cmsUsers;
/**
* @var Proxy[]
*/
private $cmsEmployees;
/**
* @var Proxy[]
*/
private $initializedUsers;
/**
* @var Proxy[]
*/
private $initializedEmployees;
public function init()
{
$proxyFactory = (new NonProxyLoadingEntityManager(EntityManagerFactory::getEntityManager([])))
->getProxyFactory();
for ($i = 0; $i < 10000; ++$i) {
$this->cmsUsers[$i] = $proxyFactory->getProxy(CmsUser::class, ['id' => $i]);
$this->cmsEmployees[$i] = $proxyFactory->getProxy(CmsEmployee::class, ['id' => $i]);
$this->initializedUsers[$i] = $proxyFactory->getProxy(CmsUser::class, ['id' => $i]);
$this->initializedEmployees[$i] = $proxyFactory->getProxy(CmsEmployee::class, ['id' => $i]);
$this->initializedUsers[$i]->__load();
$this->initializedEmployees[$i]->__load();
}
}
public function benchCmsUserInitialization()
{
foreach ($this->cmsUsers as $proxy) {
$proxy->__load();
}
}
public function benchCmsEmployeeInitialization()
{
foreach ($this->cmsEmployees as $proxy) {
$proxy->__load();
}
}
public function benchInitializationOfAlreadyInitializedCmsUsers()
{
foreach ($this->initializedUsers as $proxy) {
$proxy->__load();
}
}
public function benchInitializationOfAlreadyInitializedCmsEmployees()
{
foreach ($this->initializedEmployees as $proxy) {
$proxy->__load();
}
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace Doctrine\Performance\LazyLoading;
use Doctrine\Common\Proxy\AbstractProxyFactory;
use Doctrine\Performance\EntityManagerFactory;
use Doctrine\Tests\Models\CMS\CmsEmployee;
use Doctrine\Tests\Models\CMS\CmsUser;
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
/**
* @BeforeMethods({"init"})
*/
final class ProxyInstantiationTimeBench
{
/**
* @var AbstractProxyFactory
*/
private $proxyFactory;
public function init()
{
$this->proxyFactory = EntityManagerFactory::getEntityManager([])->getProxyFactory();
}
public function benchCmsUserInstantiation()
{
for ($i = 0; $i < 100000; ++$i) {
$this->proxyFactory->getProxy(CmsUser::class, ['id' => $i]);
}
}
public function benchCmsEmployeeInstantiation()
{
for ($i = 0; $i < 100000; ++$i) {
$this->proxyFactory->getProxy(CmsEmployee::class, ['id' => $i]);
}
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace Doctrine\Performance\Mock;
use Doctrine\ORM\Persisters\Entity\BasicEntityPersister;
use Doctrine\ORM\Query;
/**
* A persister that doesn't actually load given objects
*/
class NonLoadingPersister extends BasicEntityPersister
{
public function __construct()
{
}
/**
* {@inheritDoc}
*/
public function load(
array $criteria,
$entity = null,
$assoc = null,
array $hints = array(),
$lockMode = 0,
$limit = null,
array $orderBy = null
) {
return $entity;
}
}

View File

@ -0,0 +1,352 @@
<?php
namespace Doctrine\Performance\Mock;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Proxy\ProxyFactory;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Tests\ORM\Performance\MockUnitOfWork;
/**
* An entity manager mock that prevents lazy-loading of proxies
*/
class NonProxyLoadingEntityManager implements EntityManagerInterface
{
/**
* @var EntityManagerInterface
*/
private $realEntityManager;
public function __construct(EntityManagerInterface $realEntityManager)
{
$this->realEntityManager = $realEntityManager;
}
/**
* {@inheritDoc}
*/
public function getProxyFactory()
{
$config = $this->realEntityManager->getConfiguration();
return new ProxyFactory(
$this,
$config->getProxyDir(),
$config->getProxyNamespace(),
$config->getAutoGenerateProxyClasses()
);
}
/**
* {@inheritDoc}
*/
public function getMetadataFactory()
{
return $this->realEntityManager->getMetadataFactory();
}
/**
* {@inheritDoc}
*/
public function getClassMetadata($className)
{
return $this->realEntityManager->getClassMetadata($className);
}
/**
* {@inheritDoc}
*/
public function getUnitOfWork()
{
return new NonProxyLoadingUnitOfWork();
}
/**
* {@inheritDoc}
*/
public function getCache()
{
return $this->realEntityManager->getCache();
}
/**
* {@inheritDoc}
*/
public function getConnection()
{
return $this->realEntityManager->getConnection();
}
/**
* {@inheritDoc}
*/
public function getExpressionBuilder()
{
return $this->realEntityManager->getExpressionBuilder();
}
/**
* {@inheritDoc}
*/
public function beginTransaction()
{
$this->realEntityManager->beginTransaction();
}
/**
* {@inheritDoc}
*/
public function transactional($func)
{
return $this->realEntityManager->transactional($func);
}
/**
* {@inheritDoc}
*/
public function commit()
{
$this->realEntityManager->commit();
}
/**
* {@inheritDoc}
*/
public function rollback()
{
$this->realEntityManager->rollback();
}
/**
* {@inheritDoc}
*/
public function createQuery($dql = '')
{
return $this->realEntityManager->createQuery($dql);
}
/**
* {@inheritDoc}
*/
public function createNamedQuery($name)
{
return $this->realEntityManager->createNamedQuery($name);
}
/**
* {@inheritDoc}
*/
public function createNativeQuery($sql, ResultSetMapping $rsm)
{
return $this->realEntityManager->createNativeQuery($sql, $rsm);
}
/**
* {@inheritDoc}
*/
public function createNamedNativeQuery($name)
{
return $this->realEntityManager->createNamedNativeQuery($name);
}
/**
* {@inheritDoc}
*/
public function createQueryBuilder()
{
return $this->realEntityManager->createQueryBuilder();
}
/**
* {@inheritDoc}
*/
public function getReference($entityName, $id)
{
return $this->realEntityManager->getReference($entityName, $id);
}
/**
* {@inheritDoc}
*/
public function getPartialReference($entityName, $identifier)
{
return $this->realEntityManager->getPartialReference($entityName, $identifier);
}
/**
* {@inheritDoc}
*/
public function close()
{
$this->realEntityManager->close();
}
/**
* {@inheritDoc}
*/
public function copy($entity, $deep = false)
{
return $this->realEntityManager->copy($entity, $deep);
}
/**
* {@inheritDoc}
*/
public function lock($entity, $lockMode, $lockVersion = null)
{
$this->realEntityManager->lock($entity, $lockMode, $lockVersion);
}
/**
* {@inheritDoc}
*/
public function getEventManager()
{
return $this->realEntityManager->getEventManager();
}
/**
* {@inheritDoc}
*/
public function getConfiguration()
{
return $this->realEntityManager->getConfiguration();
}
/**
* {@inheritDoc}
*/
public function isOpen()
{
return $this->realEntityManager->isOpen();
}
/**
* {@inheritDoc}
*/
public function getHydrator($hydrationMode)
{
return $this->realEntityManager->getHydrator($hydrationMode);
}
/**
* {@inheritDoc}
*/
public function newHydrator($hydrationMode)
{
return $this->realEntityManager->newHydrator($hydrationMode);
}
/**
* {@inheritDoc}
*/
public function getFilters()
{
return $this->realEntityManager->getFilters();
}
/**
* {@inheritDoc}
*/
public function isFiltersStateClean()
{
return $this->realEntityManager->isFiltersStateClean();
}
/**
* {@inheritDoc}
*/
public function hasFilters()
{
return $this->realEntityManager->hasFilters();
}
/**
* {@inheritDoc}
*/
public function find($className, $id)
{
return $this->realEntityManager->find($className, $id);
}
/**
* {@inheritDoc}
*/
public function persist($object)
{
$this->realEntityManager->persist($object);
}
/**
* {@inheritDoc}
*/
public function remove($object)
{
$this->realEntityManager->remove($object);
}
/**
* {@inheritDoc}
*/
public function merge($object)
{
return $this->realEntityManager->merge($object);
}
/**
* {@inheritDoc}
*/
public function clear($objectName = null)
{
$this->realEntityManager->clear($objectName);
}
/**
* {@inheritDoc}
*/
public function detach($object)
{
$this->realEntityManager->detach($object);
}
/**
* {@inheritDoc}
*/
public function refresh($object)
{
$this->realEntityManager->refresh($object);
}
/**
* {@inheritDoc}
*/
public function flush()
{
$this->realEntityManager->flush();
}
/**
* {@inheritDoc}
*/
public function getRepository($className)
{
return $this->realEntityManager->getRepository($className);
}
/**
* {@inheritDoc}
*/
public function initializeObject($obj)
{
$this->realEntityManager->initializeObject($obj);
}
/**
* {@inheritDoc}
*/
public function contains($object)
{
return $this->realEntityManager->contains($object);
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace Doctrine\Performance\Mock;
use Doctrine\ORM\Query;
use Doctrine\ORM\UnitOfWork;
use Doctrine\Tests\ORM\Performance\PersisterMock;
/**
* An unit of work mock that prevents lazy-loading of proxies
*/
class NonProxyLoadingUnitOfWork extends UnitOfWork
{
/**
* @var PersisterMock
*/
private $entityPersister;
public function __construct()
{
$this->entityPersister = new NonLoadingPersister();
}
/**
* {@inheritDoc}
*/
public function getEntityPersister($entityName)
{
return $this->entityPersister;
}
}

View File

@ -1,39 +0,0 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* @group DDC-1050
*/
class DDC1050Test extends OrmFunctionalTestCase
{
public function setUp()
{
$this->markTestSkipped('performance skipped');
$this->useModelSet('cms');
parent::setUp();
}
public function testPerformance()
{
for ($i = 2; $i < 10000; ++$i) {
$user = new CmsUser();
$user->status = 'developer';
$user->username = 'jwage'.$i;
$user->name = 'Jonathan';
$this->_em->persist($user);
}
$this->_em->flush();
$this->_em->clear();
$s = microtime(true);
$users = $this->_em->getRepository(CmsUser::class)->findAll();
$e = microtime(true);
echo __FUNCTION__ . " - " . ($e - $s) . " seconds" . PHP_EOL;
}
}

View File

@ -8,7 +8,6 @@ use Doctrine\ORM\Events;
use Doctrine\Tests\OrmPerformanceTestCase;
/**
* @group performance
* @group DDC-2602
*/
class DDC2602Test extends OrmPerformanceTestCase
@ -51,14 +50,10 @@ class DDC2602Test extends OrmPerformanceTestCase
// Set maximum seconds this can run
$this->setMaxRunningTime(1);
$s = microtime(true);
$query = $this->_em->createQuery('SELECT u, b FROM Doctrine\Tests\ORM\Performance\DDC2602User u JOIN u.biography b');
$query->getResult();
$e = microtime(true);
echo __FUNCTION__ . " - " . ($e - $s) . " seconds" . PHP_EOL;
$this
->_em
->createQuery('SELECT u, b FROM Doctrine\Tests\ORM\Performance\DDC2602User u JOIN u.biography b')
->getResult();
}
private function loadFixture()

View File

@ -1,456 +0,0 @@
<?php
namespace Doctrine\Tests\ORM\Performance;
use Doctrine\ORM\Internal\Hydration\ArrayHydrator;
use Doctrine\ORM\Internal\Hydration\ObjectHydrator;
use Doctrine\ORM\Internal\Hydration\ScalarHydrator;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Tests\Mocks\HydratorMockStatement;
use Doctrine\Tests\Models\CMS\CmsAddress;
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\OrmPerformanceTestCase;
/**
* Tests to prevent serious performance regressions.
*
* IMPORTANT: Be sure to run these tests without xdebug or similar tools that
* seriously degrade performance.
*
* @author robo
* @group performance
*/
class HydrationPerformanceTest extends OrmPerformanceTestCase
{
/**
* Times for comparison:
*
* [romanb: 10000 rows => 0.7 seconds]
*
* MAXIMUM TIME: 1 second
*/
public function testSimpleQueryScalarHydrationPerformance10000Rows()
{
$rsm = new ResultSetMapping;
$rsm->addEntityResult(CmsUser::class, 'u');
$rsm->addFieldResult('u', 'u__id', 'id');
$rsm->addFieldResult('u', 'u__status', 'status');
$rsm->addFieldResult('u', 'u__username', 'username');
$rsm->addFieldResult('u', 'u__name', 'name');
// Faked result set
$resultSet = [
//row1
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
],
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
],
[
'u__id' => '2',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
]
];
for ($i = 4; $i < 10000; ++$i) {
$resultSet[] = [
'u__id' => $i,
'u__status' => 'developer',
'u__username' => 'jwage',
'u__name' => 'Jonathan',
];
}
$stmt = new HydratorMockStatement($resultSet);
$hydrator = new ScalarHydrator($this->_em);
$this->setMaxRunningTime(1);
$s = microtime(true);
$result = $hydrator->hydrateAll($stmt, $rsm);
$e = microtime(true);
echo __FUNCTION__ . " - " . ($e - $s) . " seconds" . PHP_EOL;
}
/**
* Times for comparison:
*
* [romanb: 10000 rows => 1 second]
*
* MAXIMUM TIME: 2 seconds
*/
public function testSimpleQueryArrayHydrationPerformance10000Rows()
{
$rsm = new ResultSetMapping;
$rsm->addEntityResult(CmsUser::class, 'u');
$rsm->addFieldResult('u', 'u__id', 'id');
$rsm->addFieldResult('u', 'u__status', 'status');
$rsm->addFieldResult('u', 'u__username', 'username');
$rsm->addFieldResult('u', 'u__name', 'name');
// Faked result set
$resultSet = [
//row1
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
],
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
],
[
'u__id' => '2',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
]
];
for ($i = 4; $i < 10000; ++$i) {
$resultSet[] = [
'u__id' => $i,
'u__status' => 'developer',
'u__username' => 'jwage',
'u__name' => 'Jonathan',
];
}
$stmt = new HydratorMockStatement($resultSet);
$hydrator = new ArrayHydrator($this->_em);
$this->setMaxRunningTime(2);
$s = microtime(true);
$result = $hydrator->hydrateAll($stmt, $rsm);
$e = microtime(true);
echo __FUNCTION__ . " - " . ($e - $s) . " seconds" . PHP_EOL;
}
/**
* Times for comparison:
*
* [romanb: 10000 rows => 1.4 seconds]
*
* MAXIMUM TIME: 3 seconds
*/
public function testMixedQueryFetchJoinArrayHydrationPerformance10000Rows()
{
$rsm = new ResultSetMapping;
$rsm->addEntityResult(CmsUser::class, 'u');
$rsm->addJoinedEntityResult(
CmsPhonenumber::class,
'p',
'u',
'phonenumbers'
);
$rsm->addFieldResult('u', 'u__id', 'id');
$rsm->addFieldResult('u', 'u__status', 'status');
$rsm->addFieldResult('u', 'u__username', 'username');
$rsm->addFieldResult('u', 'u__name', 'name');
$rsm->addScalarResult('sclr0', 'nameUpper');
$rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
// Faked result set
$resultSet = [
//row1
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'sclr0' => 'ROMANB',
'p__phonenumber' => '42',
],
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'sclr0' => 'ROMANB',
'p__phonenumber' => '43',
],
[
'u__id' => '2',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'sclr0' => 'JWAGE',
'p__phonenumber' => '91'
]
];
for ($i = 4; $i < 10000; ++$i) {
$resultSet[] = [
'u__id' => $i,
'u__status' => 'developer',
'u__username' => 'jwage',
'u__name' => 'Jonathan',
'sclr0' => 'JWAGE' . $i,
'p__phonenumber' => '91'
];
}
$stmt = new HydratorMockStatement($resultSet);
$hydrator = new ArrayHydrator($this->_em);
$this->setMaxRunningTime(3);
$s = microtime(true);
$result = $hydrator->hydrateAll($stmt, $rsm);
$e = microtime(true);
echo __FUNCTION__ . " - " . ($e - $s) . " seconds" . PHP_EOL;
}
/**
* [romanb: 10000 rows => 1.5 seconds]
*
* MAXIMUM TIME: 3 seconds
*/
public function testSimpleQueryPartialObjectHydrationPerformance10000Rows()
{
$rsm = new ResultSetMapping;
$rsm->addEntityResult(CmsUser::class, 'u');
$rsm->addFieldResult('u', 'u__id', 'id');
$rsm->addFieldResult('u', 'u__status', 'status');
$rsm->addFieldResult('u', 'u__username', 'username');
$rsm->addFieldResult('u', 'u__name', 'name');
// Faked result set
$resultSet = [
//row1
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
],
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
],
[
'u__id' => '2',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
]
];
for ($i = 4; $i < 10000; ++$i) {
$resultSet[] = [
'u__id' => $i,
'u__status' => 'developer',
'u__username' => 'jwage',
'u__name' => 'Jonathan',
];
}
$stmt = new HydratorMockStatement($resultSet);
$hydrator = new ObjectHydrator($this->_em);
$this->setMaxRunningTime(3);
$s = microtime(true);
$result = $hydrator->hydrateAll($stmt, $rsm, [Query::HINT_FORCE_PARTIAL_LOAD => true]);
$e = microtime(true);
echo __FUNCTION__ . " - " . ($e - $s) . " seconds" . PHP_EOL;
}
/**
* [romanb: 10000 rows => 3 seconds]
*
* MAXIMUM TIME: 4.5 seconds
*/
public function testSimpleQueryFullObjectHydrationPerformance10000Rows()
{
$rsm = new ResultSetMapping;
$rsm->addEntityResult(CmsUser::class, 'u');
$rsm->addFieldResult('u', 'u__id', 'id');
$rsm->addFieldResult('u', 'u__status', 'status');
$rsm->addFieldResult('u', 'u__username', 'username');
$rsm->addFieldResult('u', 'u__name', 'name');
$rsm->addJoinedEntityResult(
CmsAddress::class,
'a',
'u',
'address'
);
$rsm->addFieldResult('a', 'a__id', 'id');
//$rsm->addFieldResult('a', 'a__country', 'country');
//$rsm->addFieldResult('a', 'a__zip', 'zip');
//$rsm->addFieldResult('a', 'a__city', 'city');
// Faked result set
$resultSet = [
//row1
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'a__id' => '1'
]
];
for ($i = 2; $i < 10000; ++$i) {
$resultSet[] = [
'u__id' => $i,
'u__status' => 'developer',
'u__username' => 'jwage',
'u__name' => 'Jonathan',
'a__id' => $i
];
}
$stmt = new HydratorMockStatement($resultSet);
$hydrator = new ObjectHydrator($this->_em);
$this->setMaxRunningTime(5);
$s = microtime(true);
$result = $hydrator->hydrateAll($stmt, $rsm);
$e = microtime(true);
echo __FUNCTION__ . " - " . ($e - $s) . " seconds" . PHP_EOL;
}
/**
* [romanb: 2000 rows => 0.4 seconds]
*
* MAXIMUM TIME: 1 second
*/
public function testMixedQueryFetchJoinPartialObjectHydrationPerformance2000Rows()
{
$rsm = new ResultSetMapping;
$rsm->addEntityResult(CmsUser::class, 'u');
$rsm->addJoinedEntityResult(
CmsPhonenumber::class,
'p',
'u',
'phonenumbers'
);
$rsm->addFieldResult('u', 'u__id', 'id');
$rsm->addFieldResult('u', 'u__status', 'status');
$rsm->addFieldResult('u', 'u__username', 'username');
$rsm->addFieldResult('u', 'u__name', 'name');
$rsm->addScalarResult('sclr0', 'nameUpper');
$rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
// Faked result set
$resultSet = [
//row1
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'sclr0' => 'ROMANB',
'p__phonenumber' => '42',
],
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'sclr0' => 'ROMANB',
'p__phonenumber' => '43',
],
[
'u__id' => '2',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'sclr0' => 'JWAGE',
'p__phonenumber' => '91'
]
];
for ($i = 4; $i < 2000; ++$i) {
$resultSet[] = [
'u__id' => $i,
'u__status' => 'developer',
'u__username' => 'jwage',
'u__name' => 'Jonathan',
'sclr0' => 'JWAGE' . $i,
'p__phonenumber' => '91'
];
}
$stmt = new HydratorMockStatement($resultSet);
$hydrator = new ObjectHydrator($this->_em);
$this->setMaxRunningTime(1);
$s = microtime(true);
$result = $hydrator->hydrateAll($stmt, $rsm, [Query::HINT_FORCE_PARTIAL_LOAD => true]);
$e = microtime(true);
echo __FUNCTION__ . " - " . ($e - $s) . " seconds" . PHP_EOL;
}
/**
* [romanb: 2000 rows => 0.6 seconds]
*
* MAXIMUM TIME: 1 second
*/
public function testMixedQueryFetchJoinFullObjectHydrationPerformance2000Rows()
{
$rsm = new ResultSetMapping;
$rsm->addEntityResult(CmsUser::class, 'u');
$rsm->addJoinedEntityResult(CmsPhonenumber::class, 'p', 'u', 'phonenumbers');
$rsm->addFieldResult('u', 'u__id', 'id');
$rsm->addFieldResult('u', 'u__status', 'status');
$rsm->addFieldResult('u', 'u__username', 'username');
$rsm->addFieldResult('u', 'u__name', 'name');
$rsm->addScalarResult('sclr0', 'nameUpper');
$rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
$rsm->addJoinedEntityResult(CmsAddress::class, 'a', 'u', 'address');
$rsm->addFieldResult('a', 'a__id', 'id');
// Faked result set
$resultSet = [
//row1
[
'u__id' => '1',
'u__status' => 'developer',
'u__username' => 'romanb',
'u__name' => 'Roman',
'sclr0' => 'ROMANB',
'p__phonenumber' => '42',
'a__id' => '1'
]
];
for ($i = 2; $i < 2000; ++$i) {
$resultSet[] = [
'u__id' => $i,
'u__status' => 'developer',
'u__username' => 'jwage',
'u__name' => 'Jonathan',
'sclr0' => 'JWAGE' . $i,
'p__phonenumber' => '91',
'a__id' => $i
];
}
$stmt = new HydratorMockStatement($resultSet);
$hydrator = new ObjectHydrator($this->_em);
$this->setMaxRunningTime(1);
$s = microtime(true);
$result = $hydrator->hydrateAll($stmt, $rsm);
$e = microtime(true);
echo __FUNCTION__ . " - " . ($e - $s) . " seconds" . PHP_EOL;
}
}

View File

@ -1,69 +0,0 @@
<?php
namespace Doctrine\Tests\ORM\Performance;
use Doctrine\ORM\Query;
use Doctrine\Tests\Models\Company\CompanyContract;
use Doctrine\Tests\Models\Company\CompanyEmployee;
use Doctrine\Tests\Models\Company\CompanyFixContract;
use Doctrine\Tests\Models\Company\CompanyFlexContract;
use Doctrine\Tests\Models\Company\CompanyFlexUltraContract;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* @group performance
*/
class InheritancePersisterPerformanceTest extends OrmFunctionalTestCase
{
protected function setUp()
{
$this->useModelSet('company');
parent::setUp();
}
public function testCompanyContract()
{
$person = new CompanyEmployee();
$person->setName('Poor Sales Guy');
$person->setDepartment('Sales');
$person->setSalary(100);
$this->_em->persist($person);
for ($i = 0; $i < 33; $i++) {
$fix = new CompanyFixContract();
$fix->setFixPrice(1000);
$fix->setSalesPerson($person);
$fix->markCompleted();
$this->_em->persist($fix);
$flex = new CompanyFlexContract();
$flex->setSalesPerson($person);
$flex->setHoursWorked(100);
$flex->setPricePerHour(100);
$flex->markCompleted();
$this->_em->persist($flex);
$ultra = new CompanyFlexUltraContract();
$ultra->setSalesPerson($person);
$ultra->setHoursWorked(150);
$ultra->setPricePerHour(150);
$ultra->setMaxPrice(7000);
$this->_em->persist($ultra);
}
$this->_em->flush();
$this->_em->clear();
$start = microtime(true);
$contracts = $this->_em->getRepository(CompanyContract::class)->findAll();
echo "99 CompanyContract: " . number_format(microtime(true) - $start, 6) . "\n";
$this->assertEquals(99, count($contracts));
$this->_em->clear();
$start = microtime(true);
$contracts = $this->_em->getRepository(CompanyContract::class)->findAll();
echo "99 CompanyContract: " . number_format(microtime(true) - $start, 6) . "\n";
$this->assertEquals(99, count($contracts));
}
}

View File

@ -1,56 +0,0 @@
<?php
namespace Doctrine\Tests\ORM\Performance;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\OrmPerformanceTestCase;
/**
* Description of InsertPerformanceTest
*
* @author robo
* @group performance
*/
class InsertPerformanceTest extends OrmPerformanceTestCase
{
protected function setUp()
{
$this->useModelSet('cms');
parent::setUp();
}
/**
* [romanb: 10000 objects in ~8 seconds]
*/
public function testInsertPerformance()
{
$s = microtime(true);
$conn = $this->_em->getConnection();
$this->setMaxRunningTime(10);
//echo "Memory usage before: " . (memory_get_usage() / 1024) . " KB" . PHP_EOL;
$batchSize = 20;
for ($i=1; $i<=10000; ++$i) {
$user = new CmsUser;
$user->status = 'user';
$user->username = 'user' . $i;
$user->name = 'Mr.Smith-' . $i;
$this->_em->persist($user);
if (($i % $batchSize) == 0) {
$this->_em->flush();
$this->_em->clear();
}
}
//gc_collect_cycles();
//echo "Memory usage after: " . (memory_get_usage() / 1024) . " KB" . PHP_EOL;
$e = microtime(true);
echo ' Inserted 10000 objects in ' . ($e - $s) . ' seconds' . PHP_EOL;
}
}

View File

@ -1,113 +0,0 @@
<?php
namespace Doctrine\Tests\ORM\Performance;
use Doctrine\ORM\Query;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\Models\CMS\CmsGroup;
use Doctrine\Tests\Models\CMS\CmsArticle;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* @group performance
*/
class PersisterPerformanceTest extends OrmFunctionalTestCase
{
protected function setUp()
{
$this->useModelSet('cms');
parent::setUp();
}
public function testFindCmsArticle()
{
$author = new CmsUser();
$author->name = "beberlei";
$author->status = "active";
$author->username = "beberlei";
$this->_em->persist($author);
$ids = [];
for ($i = 0; $i < 100; $i++) {
$article = new CmsArticle();
$article->text = "foo";
$article->topic = "bar";
$article->user = $author;
$this->_em->persist($article);
$ids[] = $article;
}
$this->_em->flush();
$this->_em->clear();
$start = microtime(true);
$articles = $this->_em->getRepository(CmsArticle::class)->findAll();
echo "100 CmsArticle findAll(): " . number_format(microtime(true) - $start, 6) . "\n";
$this->_em->clear();
$start = microtime(true);
$articles = $this->_em->getRepository(CmsArticle::class)->findAll();
echo "100 CmsArticle findAll(): " . number_format(microtime(true) - $start, 6) . "\n";
$this->_em->clear();
$start = microtime(true);
for ($i = 0; $i < 100; $i++) {
$articles = $this->_em->getRepository(CmsArticle::class)->find($ids[$i]->id);
}
echo "100 CmsArticle find(): " . number_format(microtime(true) - $start, 6) . "\n";
$this->_em->clear();
$start = microtime(true);
for ($i = 0; $i < 100; $i++) {
$articles = $this->_em->getRepository(CmsArticle::class)->find($ids[$i]->id);
}
echo "100 CmsArticle find(): " . number_format(microtime(true) - $start, 6) . "\n";
}
public function testFindCmsGroup()
{
for ($i = 0; $i < 100; $i++) {
$group = new CmsGroup();
$group->name = "foo" . $i;
$this->_em->persist($group);
}
$this->_em->flush();
$this->_em->clear();
$start = microtime(true);
$articles = $this->_em->getRepository(CmsGroup::class)->findAll();
echo "100 CmsGroup: " . number_format(microtime(true) - $start, 6) . "\n";
$this->_em->clear();
$start = microtime(true);
$articles = $this->_em->getRepository(CmsGroup::class)->findAll();
echo "100 CmsGroup: " . number_format(microtime(true) - $start, 6) . "\n";
}
public function testFindCmsUser()
{
for ($i = 0; $i < 100; $i++) {
$user = new CmsUser();
$user->name = "beberlei";
$user->status = "active";
$user->username = "beberlei".$i;
$this->_em->persist($user);
}
$this->_em->flush();
$this->_em->clear();
$start = microtime(true);
$articles = $this->_em->getRepository(CmsUser::class)->findAll();
echo "100 CmsUser: " . number_format(microtime(true) - $start, 6) . "\n";
$this->_em->clear();
$start = microtime(true);
$articles = $this->_em->getRepository(CmsUser::class)->findAll();
echo "100 CmsUser: " . number_format(microtime(true) - $start, 6) . "\n";
}
}

View File

@ -1,155 +0,0 @@
<?php
namespace Doctrine\Tests\ORM\Performance;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Persisters\Entity\BasicEntityPersister;
use Doctrine\ORM\Proxy\ProxyFactory;
use Doctrine\ORM\UnitOfWork;
use Doctrine\Tests\Models\CMS\CmsEmployee;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\OrmPerformanceTestCase;
/**
* Performance test used to measure performance of proxy instantiation
*
* @author Marco Pivetta <ocramius@gmail.com>
* @group performance
*/
class ProxyPerformanceTest extends OrmPerformanceTestCase
{
/**
* @return array
*/
public function entitiesProvider()
{
return [
[CmsEmployee::class],
[CmsUser::class],
];
}
/**
* @dataProvider entitiesProvider
*/
public function testProxyInstantiationPerformance($entityName)
{
$proxyFactory = $this->_getEntityManager()->getProxyFactory();
$this->setMaxRunningTime(5);
$start = microtime(true);
for ($i = 0; $i < 100000; $i += 1) {
$user = $proxyFactory->getProxy($entityName, ['id' => $i]);
}
echo __FUNCTION__ . " - " . (microtime(true) - $start) . " seconds with " . $entityName . PHP_EOL;
}
/**
* @dataProvider entitiesProvider
*/
public function testProxyForcedInitializationPerformance($entityName)
{
$em = new MockEntityManager($this->_getEntityManager());
$proxyFactory = $em->getProxyFactory();
/* @var $user \Doctrine\Common\Proxy\Proxy */
$user = $proxyFactory->getProxy($entityName, ['id' => 1]);
$initializer = $user->__getInitializer();
$this->setMaxRunningTime(5);
$start = microtime(true);
for ($i = 0; $i < 100000; $i += 1) {
$user->__setInitialized(false);
$user->__setInitializer($initializer);
$user->__load();
$user->__load();
}
echo __FUNCTION__ . " - " . (microtime(true) - $start) . " seconds with " . $entityName . PHP_EOL;
}
}
/**
* Mock entity manager to fake `getPersister()`
*/
class MockEntityManager extends EntityManager
{
/** @var EntityManager */
private $em;
/** @param EntityManager $em */
public function __construct(EntityManager $em)
{
$this->em = $em;
}
/** {@inheritDoc} */
public function getProxyFactory()
{
$config = $this->em->getConfiguration();
return new ProxyFactory(
$this,
$config->getProxyDir(),
$config->getProxyNamespace(),
$config->getAutoGenerateProxyClasses()
);
}
/** {@inheritDoc} */
public function getMetadataFactory()
{
return $this->em->getMetadataFactory();
}
/** {@inheritDoc} */
public function getClassMetadata($className)
{
return $this->em->getClassMetadata($className);
}
/** {@inheritDoc} */
public function getUnitOfWork()
{
return new MockUnitOfWork();
}
}
/**
* Mock UnitOfWork manager to fake `getPersister()`
*/
class MockUnitOfWork extends UnitOfWork
{
/** @var PersisterMock */
private $entityPersister;
/** */
public function __construct()
{
$this->entityPersister = new PersisterMock();
}
/** {@inheritDoc} */
public function getEntityPersister($entityName)
{
return $this->entityPersister;
}
}
/**
* Mock persister (we don't want PHPUnit comparator API to play a role in here)
*/
class PersisterMock extends BasicEntityPersister
{
/** */
public function __construct()
{
}
/** {@inheritDoc} */
public function load(array $criteria, $entity = null, $assoc = null, array $hints = [], $lockMode = 0, $limit = null, array $orderBy = null)
{
return $entity;
}
}

View File

@ -1,50 +0,0 @@
<?php
namespace Doctrine\Tests\ORM\Performance;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\OrmPerformanceTestCase;
/**
* Description of InsertPerformanceTest
*
* @author robo
* @group performance
*/
class UnitOfWorkPerformanceTest extends OrmPerformanceTestCase
{
protected function setUp()
{
$this->useModelSet('cms');
parent::setUp();
}
public function testComputeChanges()
{
$n = 100;
$users = [];
for ($i=1; $i<=$n; ++$i) {
$user = new CmsUser;
$user->status = 'user';
$user->username = 'user' . $i;
$user->name = 'Mr.Smith-' . $i;
$this->_em->persist($user);
$users[] = $user;
}
$this->_em->flush();
foreach ($users AS $user) {
$user->status = 'other';
$user->username = $user->username . '++';
$user->name = str_replace('Mr.', 'Mrs.', $user->name);
}
$s = microtime(true);
$this->_em->flush();
$e = microtime(true);
echo ' Compute ChangeSet '.$n.' objects in ' . ($e - $s) . ' seconds' . PHP_EOL;
}
}