diff --git a/.gitignore b/.gitignore index 490413d15f7..d2f5f690158 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ lib/Doctrine/DBAL .idea vendor/ composer.lock +/tests/Doctrine/Performance/history.db diff --git a/.travis.yml b/.travis.yml index 57b2cb1f680..20c2aa3af32 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/composer.json b/composer.json index d320b0b4dd5..d632c89919d 100644 --- a/composer.json +++ b/composer.json @@ -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": { diff --git a/phpbench.json b/phpbench.json new file mode 100644 index 00000000000..74fdef412a7 --- /dev/null +++ b/phpbench.json @@ -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" + } +} diff --git a/tests/Doctrine/Performance/ChangeSet/UnitOfWorkComputeChangesBench.php b/tests/Doctrine/Performance/ChangeSet/UnitOfWorkComputeChangesBench.php new file mode 100644 index 00000000000..25cc2fffdbb --- /dev/null +++ b/tests/Doctrine/Performance/ChangeSet/UnitOfWorkComputeChangesBench.php @@ -0,0 +1,73 @@ +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(); + } +} + diff --git a/tests/Doctrine/Performance/EntityManagerFactory.php b/tests/Doctrine/Performance/EntityManagerFactory.php new file mode 100644 index 00000000000..fab5eba767c --- /dev/null +++ b/tests/Doctrine/Performance/EntityManagerFactory.php @@ -0,0 +1,39 @@ +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; + } +} diff --git a/tests/Doctrine/Performance/Hydration/MixedQueryFetchJoinArrayHydrationPerformanceBench.php b/tests/Doctrine/Performance/Hydration/MixedQueryFetchJoinArrayHydrationPerformanceBench.php new file mode 100644 index 00000000000..bbda1f23dd8 --- /dev/null +++ b/tests/Doctrine/Performance/Hydration/MixedQueryFetchJoinArrayHydrationPerformanceBench.php @@ -0,0 +1,92 @@ + '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); + } +} + diff --git a/tests/Doctrine/Performance/Hydration/MixedQueryFetchJoinFullObjectHydrationPerformanceBench.php b/tests/Doctrine/Performance/Hydration/MixedQueryFetchJoinFullObjectHydrationPerformanceBench.php new file mode 100644 index 00000000000..c70ca77cb10 --- /dev/null +++ b/tests/Doctrine/Performance/Hydration/MixedQueryFetchJoinFullObjectHydrationPerformanceBench.php @@ -0,0 +1,81 @@ + '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); + } +} + diff --git a/tests/Doctrine/Performance/Hydration/MixedQueryFetchJoinPartialObjectHydrationPerformanceBench.php b/tests/Doctrine/Performance/Hydration/MixedQueryFetchJoinPartialObjectHydrationPerformanceBench.php new file mode 100644 index 00000000000..f2e33f76dbd --- /dev/null +++ b/tests/Doctrine/Performance/Hydration/MixedQueryFetchJoinPartialObjectHydrationPerformanceBench.php @@ -0,0 +1,93 @@ + '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]); + } +} + diff --git a/tests/Doctrine/Performance/Hydration/SimpleHydrationBench.php b/tests/Doctrine/Performance/Hydration/SimpleHydrationBench.php new file mode 100644 index 00000000000..a3fd637d67e --- /dev/null +++ b/tests/Doctrine/Performance/Hydration/SimpleHydrationBench.php @@ -0,0 +1,58 @@ +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(); + } +} diff --git a/tests/Doctrine/Performance/Hydration/SimpleInsertPerformanceBench.php b/tests/Doctrine/Performance/Hydration/SimpleInsertPerformanceBench.php new file mode 100644 index 00000000000..68a933dd31e --- /dev/null +++ b/tests/Doctrine/Performance/Hydration/SimpleInsertPerformanceBench.php @@ -0,0 +1,61 @@ +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(); + } + } + } +} diff --git a/tests/Doctrine/Performance/Hydration/SimpleQueryArrayHydrationPerformanceBench.php b/tests/Doctrine/Performance/Hydration/SimpleQueryArrayHydrationPerformanceBench.php new file mode 100644 index 00000000000..aa404554dc8 --- /dev/null +++ b/tests/Doctrine/Performance/Hydration/SimpleQueryArrayHydrationPerformanceBench.php @@ -0,0 +1,81 @@ + '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); + } +} + diff --git a/tests/Doctrine/Performance/Hydration/SimpleQueryFullObjectHydrationPerformanceBench.php b/tests/Doctrine/Performance/Hydration/SimpleQueryFullObjectHydrationPerformanceBench.php new file mode 100644 index 00000000000..173001ff80c --- /dev/null +++ b/tests/Doctrine/Performance/Hydration/SimpleQueryFullObjectHydrationPerformanceBench.php @@ -0,0 +1,74 @@ + '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); + } +} + diff --git a/tests/Doctrine/Performance/Hydration/SimpleQueryPartialObjectHydrationPerformanceBench.php b/tests/Doctrine/Performance/Hydration/SimpleQueryPartialObjectHydrationPerformanceBench.php new file mode 100644 index 00000000000..55d78973fe2 --- /dev/null +++ b/tests/Doctrine/Performance/Hydration/SimpleQueryPartialObjectHydrationPerformanceBench.php @@ -0,0 +1,81 @@ + '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]); + } +} + diff --git a/tests/Doctrine/Performance/Hydration/SimpleQueryScalarHydrationPerformanceBench.php b/tests/Doctrine/Performance/Hydration/SimpleQueryScalarHydrationPerformanceBench.php new file mode 100644 index 00000000000..4af2c0791bf --- /dev/null +++ b/tests/Doctrine/Performance/Hydration/SimpleQueryScalarHydrationPerformanceBench.php @@ -0,0 +1,81 @@ + '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); + } +} + diff --git a/tests/Doctrine/Performance/Hydration/SingleTableInheritanceHydrationPerformanceBench.php b/tests/Doctrine/Performance/Hydration/SingleTableInheritanceHydrationPerformanceBench.php new file mode 100644 index 00000000000..ec6c17c3eef --- /dev/null +++ b/tests/Doctrine/Performance/Hydration/SingleTableInheritanceHydrationPerformanceBench.php @@ -0,0 +1,107 @@ +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(); + } +} diff --git a/tests/Doctrine/Performance/Hydration/SingleTableInheritanceInsertPerformanceBench.php b/tests/Doctrine/Performance/Hydration/SingleTableInheritanceInsertPerformanceBench.php new file mode 100644 index 00000000000..8014b0ed1f3 --- /dev/null +++ b/tests/Doctrine/Performance/Hydration/SingleTableInheritanceInsertPerformanceBench.php @@ -0,0 +1,100 @@ +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(); + } +} diff --git a/tests/Doctrine/Performance/LazyLoading/ProxyInitializationTimeBench.php b/tests/Doctrine/Performance/LazyLoading/ProxyInitializationTimeBench.php new file mode 100644 index 00000000000..aeb5a1d2dee --- /dev/null +++ b/tests/Doctrine/Performance/LazyLoading/ProxyInitializationTimeBench.php @@ -0,0 +1,81 @@ +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(); + } + } +} + diff --git a/tests/Doctrine/Performance/LazyLoading/ProxyInstantiationTimeBench.php b/tests/Doctrine/Performance/LazyLoading/ProxyInstantiationTimeBench.php new file mode 100644 index 00000000000..da5a2c94ff9 --- /dev/null +++ b/tests/Doctrine/Performance/LazyLoading/ProxyInstantiationTimeBench.php @@ -0,0 +1,40 @@ +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]); + } + } +} + diff --git a/tests/Doctrine/Performance/Mock/NonLoadingPersister.php b/tests/Doctrine/Performance/Mock/NonLoadingPersister.php new file mode 100644 index 00000000000..35881c5a94b --- /dev/null +++ b/tests/Doctrine/Performance/Mock/NonLoadingPersister.php @@ -0,0 +1,31 @@ +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); + } +} \ No newline at end of file diff --git a/tests/Doctrine/Performance/Mock/NonProxyLoadingUnitOfWork.php b/tests/Doctrine/Performance/Mock/NonProxyLoadingUnitOfWork.php new file mode 100644 index 00000000000..dd9139ae778 --- /dev/null +++ b/tests/Doctrine/Performance/Mock/NonProxyLoadingUnitOfWork.php @@ -0,0 +1,31 @@ +entityPersister = new NonLoadingPersister(); + } + + /** + * {@inheritDoc} + */ + public function getEntityPersister($entityName) + { + return $this->entityPersister; + } +} diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1050Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1050Test.php deleted file mode 100644 index 12c3898d858..00000000000 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1050Test.php +++ /dev/null @@ -1,39 +0,0 @@ -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; - } -} diff --git a/tests/Doctrine/Tests/ORM/Performance/DDC2602Test.php b/tests/Doctrine/Tests/ORM/Performance/DDC2602Test.php index 618b5f9c606..de8bedfc7d1 100644 --- a/tests/Doctrine/Tests/ORM/Performance/DDC2602Test.php +++ b/tests/Doctrine/Tests/ORM/Performance/DDC2602Test.php @@ -8,7 +8,6 @@ use Doctrine\Tests\OrmPerformanceTestCase; /** - * @group performance * @group DDC-2602 */ class DDC2602Test extends OrmPerformanceTestCase @@ -51,14 +50,10 @@ public function testIssue() // 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() diff --git a/tests/Doctrine/Tests/ORM/Performance/HydrationPerformanceTest.php b/tests/Doctrine/Tests/ORM/Performance/HydrationPerformanceTest.php deleted file mode 100644 index 0035222adb8..00000000000 --- a/tests/Doctrine/Tests/ORM/Performance/HydrationPerformanceTest.php +++ /dev/null @@ -1,456 +0,0 @@ - 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; - } -} - diff --git a/tests/Doctrine/Tests/ORM/Performance/InheritancePersisterPerformanceTest.php b/tests/Doctrine/Tests/ORM/Performance/InheritancePersisterPerformanceTest.php deleted file mode 100644 index 726389a4c1c..00000000000 --- a/tests/Doctrine/Tests/ORM/Performance/InheritancePersisterPerformanceTest.php +++ /dev/null @@ -1,69 +0,0 @@ -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)); - } -} diff --git a/tests/Doctrine/Tests/ORM/Performance/InsertPerformanceTest.php b/tests/Doctrine/Tests/ORM/Performance/InsertPerformanceTest.php deleted file mode 100644 index db5455b062d..00000000000 --- a/tests/Doctrine/Tests/ORM/Performance/InsertPerformanceTest.php +++ /dev/null @@ -1,56 +0,0 @@ -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; - } -} - diff --git a/tests/Doctrine/Tests/ORM/Performance/PersisterPerformanceTest.php b/tests/Doctrine/Tests/ORM/Performance/PersisterPerformanceTest.php deleted file mode 100644 index 30494d49bae..00000000000 --- a/tests/Doctrine/Tests/ORM/Performance/PersisterPerformanceTest.php +++ /dev/null @@ -1,113 +0,0 @@ -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"; - } -} diff --git a/tests/Doctrine/Tests/ORM/Performance/ProxyPerformanceTest.php b/tests/Doctrine/Tests/ORM/Performance/ProxyPerformanceTest.php deleted file mode 100644 index d73964dcc4a..00000000000 --- a/tests/Doctrine/Tests/ORM/Performance/ProxyPerformanceTest.php +++ /dev/null @@ -1,155 +0,0 @@ - - * @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; - } -} diff --git a/tests/Doctrine/Tests/ORM/Performance/UnitOfWorkPerformanceTest.php b/tests/Doctrine/Tests/ORM/Performance/UnitOfWorkPerformanceTest.php deleted file mode 100644 index 3d63eb4d844..00000000000 --- a/tests/Doctrine/Tests/ORM/Performance/UnitOfWorkPerformanceTest.php +++ /dev/null @@ -1,50 +0,0 @@ -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; - } -}