Skip to content

Commit 8574667

Browse files
authored
⚡️ Improve performance of DataFixtures (#963)
1 parent 36ddbe8 commit 8574667

File tree

4 files changed

+52
-34
lines changed

4 files changed

+52
-34
lines changed

src/DataFixtures/LoadRandomAliasData.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Doctrine\Bundle\FixturesBundle\Fixture;
1010
use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
1111
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
12+
use Doctrine\ORM\EntityManagerInterface;
1213
use Doctrine\Persistence\ObjectManager;
1314
use Override;
1415

@@ -17,23 +18,31 @@ final class LoadRandomAliasData extends Fixture implements FixtureGroupInterface
1718
#[Override]
1819
public function load(ObjectManager $manager): void
1920
{
21+
assert($manager instanceof EntityManagerInterface);
22+
2023
$user = $manager->getRepository(User::class)->findByEmail('[email protected]');
2124

2225
for ($i = 1; $i < 5; ++$i) {
2326
$alias = AliasFactory::create($user, null);
24-
2527
$manager->persist($alias);
2628
}
29+
$manager->flush();
2730

28-
$users = $manager->getRepository(User::class)->findAll();
31+
$userIds = $manager->getRepository(User::class)->createQueryBuilder('u')
32+
->select('u.id')
33+
->getQuery()
34+
->getSingleColumnResult();
2935

3036
for ($i = 1; $i < 500; ++$i) {
31-
$alias = AliasFactory::create($users[random_int(0, count($users) - 1)], 'alias'.$i);
37+
$userId = $userIds[array_rand($userIds)];
38+
$user = $manager->getReference(User::class, $userId);
39+
$alias = AliasFactory::create($user, 'alias'.$i);
3240

3341
$manager->persist($alias);
3442

35-
if (($i % 100) === 0) {
43+
if (($i % 250) === 0) {
3644
$manager->flush();
45+
$manager->clear();
3746
}
3847
}
3948

src/DataFixtures/LoadRandomUserData.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,16 @@
1313

1414
final class LoadRandomUserData extends AbstractUserData implements FixtureGroupInterface
1515
{
16+
private const BATCH_SIZE = 500;
17+
1618
#[Override]
1719
public function load(ObjectManager $manager): void
1820
{
19-
$domainRepository = $manager->getRepository(Domain::class);
20-
$domain = $domainRepository->findOneBy(['name' => 'example.org']);
21+
$domain = $manager->getRepository(Domain::class)->findOneBy(['name' => 'example.org']);
2122
$roles = [Roles::USER];
2223

2324
for ($i = 0; $i < 15000; ++$i) {
24-
$email = sprintf('user-%d@%s', $i, $domain->getName());
25-
26-
$user = $this->buildUser($domain, $email, $roles);
25+
$user = $this->buildUser($domain, sprintf('user-%d@%s', $i, $domain->getName()), $roles);
2726
$user->setCreationTime(new DateTime(sprintf('-%s days', random_int(1, 25))));
2827

2928
if (0 === $i % 20) {
@@ -36,8 +35,11 @@ public function load(ObjectManager $manager): void
3635

3736
$manager->persist($user);
3837

39-
if (($i % 100) === 0) {
38+
if (($i % self::BATCH_SIZE) === 0) {
4039
$manager->flush();
40+
$manager->clear();
41+
// Re-fetch domain after clear
42+
$domain = $manager->getRepository(Domain::class)->findOneBy(['name' => 'example.org']);
4143
}
4244
}
4345

src/DataFixtures/LoadReservedNameData.php

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,14 @@
44

55
namespace App\DataFixtures;
66

7-
use App\Creator\ReservedNameCreator;
8-
use App\Exception\ValidationException;
7+
use App\Factory\ReservedNameFactory;
98
use Doctrine\Bundle\FixturesBundle\Fixture;
109
use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
1110
use Doctrine\Persistence\ObjectManager;
1211
use Override;
1312

1413
final class LoadReservedNameData extends Fixture implements FixtureGroupInterface
1514
{
16-
/**
17-
* LoadReservedNameData constructor.
18-
*/
19-
public function __construct(private readonly ReservedNameCreator $creator)
20-
{
21-
}
22-
23-
/**
24-
* @throws ValidationException
25-
*/
2615
#[Override]
2716
public function load(ObjectManager $manager): void
2817
{
@@ -31,19 +20,26 @@ public function load(ObjectManager $manager): void
3120
'r'
3221
);
3322

23+
$count = 0;
3424
while ($line = fgets($handle)) {
3525
$name = trim($line);
36-
if (empty($name)) {
26+
if (empty($name) || '#' === $name[0]) {
3727
continue;
3828
}
3929

40-
if ('#' === $name[0]) {
41-
// filter out comments
42-
continue;
43-
}
30+
$reservedName = ReservedNameFactory::create($name);
31+
$manager->persist($reservedName);
32+
++$count;
4433

45-
$this->creator->create($name);
34+
if (($count % 250) === 0) {
35+
$manager->flush();
36+
$manager->clear();
37+
}
4638
}
39+
40+
fclose($handle);
41+
$manager->flush();
42+
$manager->clear();
4743
}
4844

4945
#[Override]

src/DataFixtures/LoadVoucherData.php

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Doctrine\Bundle\FixturesBundle\Fixture;
1111
use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
1212
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
13+
use Doctrine\ORM\EntityManagerInterface;
1314
use Doctrine\Persistence\ObjectManager;
1415
use Exception;
1516
use Override;
@@ -22,12 +23,21 @@ final class LoadVoucherData extends Fixture implements FixtureGroupInterface, De
2223
#[Override]
2324
public function load(ObjectManager $manager): void
2425
{
25-
$users = $manager->getRepository(User::class)->findAll();
26+
assert($manager instanceof EntityManagerInterface);
27+
28+
$userIds = $manager->getRepository(User::class)->createQueryBuilder('u')
29+
->select('u.id')
30+
->getQuery()
31+
->getSingleColumnResult();
32+
33+
$suspiciousUser = $manager->getRepository(User::class)->findByEmail('[email protected]');
34+
$suspiciousUserId = $suspiciousUser->getId();
2635

2736
for ($i = 0; $i < 1000; ++$i) {
28-
$voucher = VoucherFactory::create($users[random_int(1, count($users) - 1)]);
37+
$user = $manager->getReference(User::class, $userIds[array_rand($userIds)]);
38+
$voucher = VoucherFactory::create($user);
2939

30-
$invitedUser = $users[random_int(0, count($users) - 1)];
40+
$invitedUser = $manager->getReference(User::class, $userIds[array_rand($userIds)]);
3141
$voucher->setInvitedUser($invitedUser);
3242
$voucher->setRedeemedTime(new DateTime());
3343

@@ -39,15 +49,16 @@ public function load(ObjectManager $manager): void
3949

4050
$manager->persist($voucher);
4151

42-
if (($i % 100) === 0) {
52+
if (($i % 250) === 0) {
4353
$manager->flush();
54+
$manager->clear();
4455
}
4556
}
4657

4758
// add redeemed voucher to a suspicious parent
48-
$user = $manager->getRepository(User::class)->findByEmail('[email protected]');
59+
$user = $manager->getReference(User::class, $suspiciousUserId);
4960
$voucher = VoucherFactory::create($user);
50-
$invitedUser = $users[random_int(0, count($users) - 1)];
61+
$invitedUser = $manager->getReference(User::class, $userIds[array_rand($userIds)]);
5162
$voucher->setInvitedUser($invitedUser);
5263
$voucher->setRedeemedTime(new DateTime(sprintf('-%d days', 100)));
5364

0 commit comments

Comments
 (0)