960a437d46
As previously reported by @flaushi in https://github.com/doctrine/doctrine2/pull/7471#discussion_r241949045, we discovered that binding a parameter causes a `ClassMetadataFactory#getClassMetadata()` call, which in turn leads to large performance regression when using any `object` type as parameter. Following two snippets lead to an internal `ClassMetadataFactory#getClassMetadata()` call, which in turn leads to an exception being thrown and garbage collected, plus multiple associated performance implications: ```php $query->setParameter('foo', new DateTime()); $query->getResult(); ``` ```php $query->setParameter('foo', new DateTime(), DateTimeType::NAME); $query->getResult(); ``` This is due to following portion of code:434820973c/lib/Doctrine/ORM/Query.php (L406-L409)
Notice how `$value = $this->processParameterValue($value);` happens before attempting to infer the type for the parameter value. That call leads to this segment being reached, which leads to the regression:434820973c/lib/Doctrine/ORM/AbstractQuery.php (L423-L433)
Assuming the bound parameter type is provided, we can completely skip attempting to introspect the given object: ```php $query->setParameter('foo', new DateTime(), DateTimeType::NAME); $query->getResult(); ``` Processing the parameter value is not needed in this case, so we can safely skip that logic for all known parameters. In order to not introduce a BC break or change the `AbstractQuery#processParameterValue()` implementation, we could filter out all parameters for which the type is given upfront, and later on merge them back in instead. The test expectation to be set is for `UnitOfWork#getSingleIdentifierValue()` to never be called.
Running the Doctrine 2 Testsuite
To execute the Doctrine2 testsuite, you just need to execute this simple steps:
- Clone the project from GitHub
- Enter the Doctrine2 folder
- Install the dependencies
- Execute the tests
All this is (normally) done with:
git clone git@github.com:doctrine/doctrine2.git
cd doctrine2
composer install
./vendor/bin/phpunit
Pre-requisites
Doctrine2 works on many database vendors; the tests can detect the presence of installed vendors, but you need at least one of those; the easier to install is SQLite.
If you're using Debian, or a Debian-derivate Linux distribution (like Ubuntu), you can install SQLite with:
sudo apt-get install sqlite
Testing Lock-Support
The Lock support in Doctrine 2 is tested using Gearman, which allows to run concurrent tasks in parallel. Install Gearman with PHP as follows:
- Go to http://www.gearman.org and download the latest Gearman Server
- Compile it and then call ldconfig
- Start it up "gearmand -vvvv"
- Install pecl/gearman by calling "gearman-beta"
You can then go into tests/
and start up two workers:
php Doctrine/Tests/ORM/Functional/Locking/LockAgentWorker.php
Then run the locking test-suite:
phpunit --configuration <myconfig.xml> Doctrine/Tests/ORM/Functional/Locking/GearmanLockTest.php
This can run considerable time, because it is using sleep() to test for the timing ranges of locks.