Skip to content

Commit

Permalink
Fix performance issues with Wildcard resolver
Browse files Browse the repository at this point in the history
Due to an extremely inefficient algorithm, the usage of wildcard was nearly impractical (14min to generate 4K objects)
versus 1min30 now.
  • Loading branch information
theofidry committed Nov 12, 2016
1 parent 19f06ac commit 7843c89
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 20 deletions.
7 changes: 6 additions & 1 deletion src/FixtureBag.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ public function get(string $id): FixtureInterface
*/
public function getIterator()
{
return new \ArrayIterator(array_values($this->fixtures));
return new \ArrayIterator($this->fixtures);
}

public function toArray(): array
{
return $this->fixtures;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ final class FixtureWildcardReferenceResolver implements ChainableValueResolverIn
*/
private $resolver;

private $idsByPattern = [];

public function __construct(ValueResolverInterface $resolver = null)
{
$this->resolver = $resolver;
Expand Down Expand Up @@ -108,26 +110,25 @@ public function resolve(
*/
private function getSuitableIds(FixtureMatchReferenceValue $value, ResolvedFixtureSet $fixtureSet): array
{
$ids = [];

$fixtures = $fixtureSet->getFixtures();
foreach ($fixtures as $fixture) {
/** @var FixtureInterface $fixture */
$id = $fixture->getId();
if ($value->match($id)) {
$ids[$id] = true;
}
if (array_key_exists($pattern = $value->getValue(), $this->idsByPattern)) {
return $this->idsByPattern[$pattern];
}

$objects = $fixtureSet->getObjects();
foreach ($objects as $object) {
/** @var ObjectInterface $object */
$id = $object->getId();
if ($value->match($id)) {
$ids[$id] = true;
}
}
$fixtureKeys = array_flip(
preg_grep(
$pattern,
array_keys($fixtureSet->getFixtures()->toArray())
)
);
$objectKeys = array_flip(
preg_grep(
$pattern,
array_keys($fixtureSet->getObjects()->toArray())
)
);

$this->idsByPattern[$pattern] = array_keys($fixtureKeys + $objectKeys);

return array_keys($ids);
return $this->idsByPattern[$pattern];
}
}
21 changes: 20 additions & 1 deletion tests/FixtureBagTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,26 @@ public function testIsIterable()
$fixtures[$key] = $value;
}

$this->assertSame($fixtures, array_values($this->propRefl->getValue($bag)));
$this->assertSame($fixtures, $this->propRefl->getValue($bag));
}

public function testToArray()
{
$fixture1 = new DummyFixture('foo');
$fixture2 = new DummyFixture('bar');

$bag = (new FixtureBag())
->with($fixture1)
->with($fixture2)
;

$this->assertEquals(
[
'foo' => $fixture1,
'bar' => $fixture2,
],
$bag->toArray()
);
}

private function assertSameFixtures(array $expected, FixtureBag $actual)
Expand Down

0 comments on commit 7843c89

Please sign in to comment.