Skip to content

Commit

Permalink
Merge pull request #415 from patchlevel/more-benchmark
Browse files Browse the repository at this point in the history
add more benchmark tests
  • Loading branch information
DanielBadura authored Dec 13, 2023
2 parents c5fcee7 + 6134991 commit bd34952
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 38 deletions.
11 changes: 6 additions & 5 deletions baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,30 +82,31 @@
<code>$name</code>
</PropertyNotSetInConstructor>
</file>
<file src="tests/Benchmark/LoadEventsBench.php">
<file src="tests/Benchmark/SimpleSetupBench.php">
<MissingConstructor>
<code>$bus</code>
<code>$repository</code>
<code>$store</code>
</MissingConstructor>
</file>
<file src="tests/Benchmark/LoadEventsWithSnapshotsBench.php">
<file src="tests/Benchmark/SnapshotsBench.php">
<MissingConstructor>
<code>$adapter</code>
<code>$bus</code>
<code>$repository</code>
<code>$snapshotStore</code>
<code>$store</code>
</MissingConstructor>
</file>
<file src="tests/Benchmark/WriteEventsBench.php">
<file src="tests/Benchmark/SplitStreamBench.php">
<MissingConstructor>
<code>$bus</code>
<code>$profile</code>
<code>$repository</code>
<code>$snapshotStore</code>
<code>$store</code>
</MissingConstructor>
</file>
<file src="tests/Benchmark/WriteEventsWithSyncProjectionistBench.php">
<file src="tests/Benchmark/SyncProjectionistBench.php">
<MissingConstructor>
<code>$bus</code>
<code>$profile</code>
Expand Down
5 changes: 5 additions & 0 deletions src/Snapshot/Adapter/InMemorySnapshotAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,9 @@ public function load(string $key): array

return $this->snapshots[$key];
}

public function clear(): void
{
$this->snapshots = [];
}
}
16 changes: 16 additions & 0 deletions tests/Benchmark/BasicImplementation/Aggregate/Profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Patchlevel\EventSourcing\Attribute\Snapshot;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Events\NameChanged;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Events\ProfileCreated;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Events\Reborn;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Normalizer\ProfileIdNormalizer;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\ProfileId;

Expand Down Expand Up @@ -39,6 +40,14 @@ public function changeName(string $name): void
$this->recordThat(new NameChanged($name));
}

public function reborn(): void
{
$this->recordThat(new Reborn(
$this->id,
$this->name,
));
}

#[Apply]
protected function applyProfileCreated(ProfileCreated $event): void
{
Expand All @@ -52,6 +61,13 @@ protected function applyNameChanged(NameChanged $event): void
$this->name = $event->name;
}

#[Apply]
protected function applyReborn(Reborn $event): void
{
$this->id = $event->profileId;
$this->name = $event->name;
}

public function name(): string
{
return $this->name;
Expand Down
22 changes: 22 additions & 0 deletions tests/Benchmark/BasicImplementation/Events/Reborn.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Events;

use Patchlevel\EventSourcing\Attribute\Event;
use Patchlevel\EventSourcing\Attribute\SplitStream;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Normalizer\ProfileIdNormalizer;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\ProfileId;

#[Event('profile.reborn')]
#[SplitStream]
final class Reborn
{
public function __construct(
#[ProfileIdNormalizer]
public ProfileId $profileId,
public string $name,
) {
}
}
7 changes: 7 additions & 0 deletions tests/Benchmark/BasicImplementation/ProfileId.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation;

use function uniqid;

final class ProfileId
{
private function __construct(
Expand All @@ -20,4 +22,9 @@ public function toString(): string
{
return $this->id;
}

public static function generate(): self
{
return new self(uniqid('', true));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
use function unlink;

#[Bench\BeforeMethods('setUp')]
final class LoadEventsBench
final class SimpleSetupBench
{
private const DB_PATH = __DIR__ . '/BasicImplementation/data/db.sqlite3';

Expand Down Expand Up @@ -74,4 +74,23 @@ public function benchLoad10000Events(): void
{
$this->repository->load('1');
}

#[Bench\Revs(20)]
public function benchSave1Event(): void
{
$profile = Profile::create(ProfileId::generate(), 'Peter');
$this->repository->save($profile);
}

#[Bench\Revs(20)]
public function benchSave10000Events(): void
{
$profile = Profile::create(ProfileId::generate(), 'Peter');

for ($i = 1; $i < 10_000; $i++) {
$profile->changeName('Peter');
}

$this->repository->save($profile);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
use function unlink;

#[Bench\BeforeMethods('setUp')]
final class LoadEventsWithSnapshotsBench
final class SnapshotsBench
{
private const DB_PATH = __DIR__ . '/BasicImplementation/data/db.sqlite3';

Expand All @@ -35,6 +35,8 @@ final class LoadEventsWithSnapshotsBench
private SnapshotStore $snapshotStore;
private Repository $repository;

private InMemorySnapshotAdapter $adapter;

public function setUp(): void
{
if (file_exists(self::DB_PATH)) {
Expand All @@ -55,7 +57,9 @@ public function setUp(): void
'eventstore',
);

$this->snapshotStore = new DefaultSnapshotStore(['default' => new InMemorySnapshotAdapter()]);
$this->adapter = new InMemorySnapshotAdapter();

$this->snapshotStore = new DefaultSnapshotStore(['default' => $this->adapter]);

$this->repository = new DefaultRepository($this->store, $this->bus, Profile::metadata(), $this->snapshotStore);

Expand All @@ -76,6 +80,13 @@ public function setUp(): void
$this->snapshotStore->save($profile);
}

#[Bench\Revs(20)]
public function benchLoad10000EventsMissingSnapshot(): void
{
$this->adapter->clear();
$this->repository->load('1');
}

#[Bench\Revs(20)]
public function benchLoad10000Events(): void
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,35 @@

use Doctrine\DBAL\Driver\PDO\SQLite\Driver;
use Doctrine\DBAL\DriverManager;
use Patchlevel\EventSourcing\EventBus\Decorator\SplitStreamDecorator;
use Patchlevel\EventSourcing\EventBus\DefaultEventBus;
use Patchlevel\EventSourcing\EventBus\EventBus;
use Patchlevel\EventSourcing\Metadata\AggregateRoot\AttributeAggregateRootRegistryFactory;
use Patchlevel\EventSourcing\Projection\Projection\Store\InMemoryStore;
use Patchlevel\EventSourcing\Projection\Projectionist\DefaultProjectionist;
use Patchlevel\EventSourcing\Projection\Projector\InMemoryProjectorRepository;
use Patchlevel\EventSourcing\Metadata\Event\AttributeEventMetadataFactory;
use Patchlevel\EventSourcing\Repository\DefaultRepository;
use Patchlevel\EventSourcing\Repository\Repository;
use Patchlevel\EventSourcing\Schema\DoctrineSchemaDirector;
use Patchlevel\EventSourcing\Serializer\DefaultEventSerializer;
use Patchlevel\EventSourcing\Snapshot\SnapshotStore;
use Patchlevel\EventSourcing\Store\DoctrineDbalStore;
use Patchlevel\EventSourcing\Store\Store;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Aggregate\Profile;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Processor\SendEmailProcessor;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\ProfileId;
use Patchlevel\EventSourcing\Tests\Benchmark\BasicImplementation\Projection\ProfileProjector;
use PhpBench\Attributes as Bench;

use function file_exists;
use function sprintf;
use function unlink;

#[Bench\BeforeMethods('setUp')]
final class WriteEventsBench
final class SplitStreamBench
{
private const DB_PATH = __DIR__ . '/BasicImplementation/data/db.sqlite3';

private Store $store;
private EventBus $bus;
private SnapshotStore $snapshotStore;
private Repository $repository;
private Profile $profile;

public function setUp(): void
{
Expand All @@ -48,55 +47,72 @@ public function setUp(): void
'path' => self::DB_PATH,
]);

$this->bus = new DefaultEventBus();

$this->store = new DoctrineDbalStore(
$connection,
DefaultEventSerializer::createFromPaths([__DIR__ . '/BasicImplementation/Events']),
(new AttributeAggregateRootRegistryFactory())->create([__DIR__ . '/BasicImplementation/Aggregate']),
'eventstore',
);

$profileProjection = new ProfileProjector($connection);
$projectionRepository = new InMemoryProjectorRepository(
[$profileProjection],
);

$projectionist = new DefaultProjectionist(
$this->repository = new DefaultRepository(
$this->store,
new InMemoryStore(),
$projectionRepository,
$this->bus,
Profile::metadata(),
null,
new SplitStreamDecorator(
new AttributeEventMetadataFactory(),
),
);

$this->bus = new DefaultEventBus();
$this->bus->addListener(new SendEmailProcessor());

$this->repository = new DefaultRepository($this->store, $this->bus, Profile::metadata());

$schemaDirector = new DoctrineSchemaDirector(
$connection,
$this->store,
);

$schemaDirector->create();
$projectionist->boot();
}

public function provideData(): void
{
$profile = Profile::create(ProfileId::fromString('1'), 'Peter');

for ($i = 0; $i < 10_000; $i++) {
$profile->changeName(sprintf('Peter %d', $i));

$this->profile = Profile::create(ProfileId::fromString('1'), 'Peter');
$this->repository->save($this->profile);
if ($i % 100 !== 0) {
continue;
}

$profile->reborn();
}

$this->repository->save($profile);
}

#[Bench\Revs(20)]
public function benchSave1Event(): void
#[Bench\BeforeMethods('provideData')]
public function benchLoad10000Events(): void
{
$this->profile->changeName('Peter');
$this->repository->save($this->profile);
$this->repository->load('1');
}

#[Bench\Revs(20)]
public function benchSave10000Events(): void
public function benchWrite10000Events(): void
{
$profile = Profile::create(ProfileId::generate(), 'Peter');

for ($i = 0; $i < 10_000; $i++) {
$this->profile->changeName('Peter');
$profile->changeName(sprintf('Peter %d', $i));

if ($i % 100 !== 0) {
continue;
}

$profile->reborn();
}

$this->repository->save($this->profile);
$this->repository->save($profile);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
use function unlink;

#[Bench\BeforeMethods('setUp')]
final class WriteEventsWithSyncProjectionistBench
final class SyncProjectionistBench
{
private const DB_PATH = __DIR__ . '/BasicImplementation/data/db.sqlite3';

Expand Down

0 comments on commit bd34952

Please sign in to comment.