Significant performance degradation with enable_lazy_ghost_objects: true #7259

Open
opened 2026-01-22 15:48:22 +01:00 by admin · 0 comments
Owner

Originally created by @javer on GitHub (Nov 25, 2023).

Bug Report

Q A
BC Break no
Version 2.17.1

Summary

After updating ORM from 2.15.2 to 2.17.1 and turning on enable_lazy_ghost_objects as it's suggested I've noticed a significant performance degradation during test suite running. The overall suite became slower by noticeable 30%. Localizing the slow spot I've found that ProxyReferenceRepository::load() now takes 50 seconds in total instead of the previous 3.86 seconds, i.e. became 13x slower.
Tracking down ProxyReferenceRepository::load() -> ProxyReferenceRepository::unserialize() I've found that EntityManager::getReference() became 23x slower (2.055 seconds -> 47.888 seconds in total). This real project has hundreds of entities and complex relations between them. During running test suite with 1k+ scenarios a lot of fixtures are generated, saved and loaded (including references):

Time in seconds enable_lazy_ghost_objects: false enable_lazy_ghost_objects: true Slowdown
EntityManager::getReference() 2.055900 47.887696 23.29x
UnitOfWork::tryGetById() 0.277827 9.693281 34.89x
ProxyFactory::getProxy() 0.751345 27.942798 37.19x
UnitOfWork::registerManaged() 0.611383 9.814827 16.05x

I've created a test command to reproduce the issue, and running it in the same project I get:

Time in seconds enable_lazy_ghost_objects: false enable_lazy_ghost_objects: true Slowdown
Total 1.922614 8.043023 4.18x
EntityManager::getReference() 1.784766 7.948818 4.45x
UnitOfWork::tryGetById() 0.232570 0.254660 1.09x
ProxyFactory::getProxy() 0.605608 4.091646 6.76x
UnitOfWork::registerManaged() 0.547479 3.200220 5.85x

I've created a small reproducer: https://github.com/javer/doctrine-orm-lazy-ghost
It's a fresh Symfony 6.3 project with one additional commit: 36a3e20b93
Running bin/console app:test:orm I have the following results:

Time in seconds enable_lazy_ghost_objects: false enable_lazy_ghost_objects: true Slowdown
Total 2.388989 4.273117 1.79x
UnitOfWork::tryGetById() 0.340158 0.349181 1.03x
ProxyFactory::getProxy() 0.709970 2.551538 3.59x
UnitOfWork::registerManaged() 0.776654 0.818202 1.05x

Slowdown numbers are not so high as in a real project, but there is only one simple entity without any relations, and no save/load operations, only getting references. Even in this simple case ProxyFactory::getProxy() slowdown by almost 4x is too expensive for using enable_lazy_ghost_objects.

Taking into account that enable_lazy_ghost_objects will be always true in ORM 3.0 I think it's worth fixing it.

How to reproduce

git clone https://github.com/javer/doctrine-orm-lazy-ghost
cd doctrine-orm-lazy-ghost
composer install
bin/console app:test:orm

Expected behavior

Turning on enable_lazy_ghost_objects shouldn't have a noticeable impact on the performance.

Originally created by @javer on GitHub (Nov 25, 2023). ### Bug Report | Q | A |------------ | ------ | BC Break | no | Version | 2.17.1 #### Summary After updating ORM from 2.15.2 to 2.17.1 and turning on `enable_lazy_ghost_objects` as it's suggested I've noticed a significant performance degradation during test suite running. The overall suite became slower by noticeable 30%. Localizing the slow spot I've found that [ProxyReferenceRepository::load()](https://github.com/doctrine/data-fixtures/blob/1.7.x/src/ProxyReferenceRepository.php#L101) now takes 50 seconds in total instead of the previous 3.86 seconds, i.e. became 13x slower. Tracking down `ProxyReferenceRepository::load()` -> `ProxyReferenceRepository::unserialize()` I've found that `EntityManager::getReference()` became 23x slower (2.055 seconds -> 47.888 seconds in total). This real project has hundreds of entities and complex relations between them. During running test suite with 1k+ scenarios a lot of fixtures are generated, saved and loaded (including references): Time in seconds | enable_lazy_ghost_objects: false | enable_lazy_ghost_objects: true | Slowdown ------------------------------|----------------------------------|---------------------------------|--------- EntityManager::getReference() | 2.055900 | 47.887696 | 23.29x UnitOfWork::tryGetById() | 0.277827 | 9.693281 | 34.89x ProxyFactory::getProxy() | 0.751345 | 27.942798 | 37.19x UnitOfWork::registerManaged() | 0.611383 | 9.814827 | 16.05x I've created a test command to reproduce the issue, and running it in the same project I get: Time in seconds | enable_lazy_ghost_objects: false | enable_lazy_ghost_objects: true | Slowdown ------------------------------|----------------------------------|---------------------------------|--------- Total | 1.922614 | 8.043023 | 4.18x EntityManager::getReference() | 1.784766 | 7.948818 | 4.45x UnitOfWork::tryGetById() | 0.232570 | 0.254660 | 1.09x ProxyFactory::getProxy() | 0.605608 | 4.091646 | 6.76x UnitOfWork::registerManaged() | 0.547479 | 3.200220 | 5.85x I've created a small reproducer: https://github.com/javer/doctrine-orm-lazy-ghost It's a fresh Symfony 6.3 project with one additional commit: https://github.com/javer/doctrine-orm-lazy-ghost/commit/36a3e20b93fe5dba1a520a24351ad794477185e9 Running `bin/console app:test:orm` I have the following results: Time in seconds | enable_lazy_ghost_objects: false | enable_lazy_ghost_objects: true | Slowdown ------------------------------|----------------------------------|---------------------------------|--------- Total | 2.388989 | 4.273117 | 1.79x UnitOfWork::tryGetById() | 0.340158 | 0.349181 | 1.03x ProxyFactory::getProxy() | 0.709970 | 2.551538 | 3.59x UnitOfWork::registerManaged() | 0.776654 | 0.818202 | 1.05x Slowdown numbers are not so high as in a real project, but there is only one simple entity without any relations, and no save/load operations, only getting references. Even in this simple case `ProxyFactory::getProxy()` slowdown by almost 4x is too expensive for using `enable_lazy_ghost_objects`. Taking into account that `enable_lazy_ghost_objects` will be always `true` in ORM 3.0 I think it's worth fixing it. #### How to reproduce ```sh git clone https://github.com/javer/doctrine-orm-lazy-ghost cd doctrine-orm-lazy-ghost composer install bin/console app:test:orm ``` #### Expected behavior Turning on `enable_lazy_ghost_objects` shouldn't have a noticeable impact on the performance.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#7259