Skip to content

Commit

Permalink
optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
alexpts committed Feb 16, 2020
1 parent 484c585 commit 6e5d65c
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 37 deletions.
103 changes: 103 additions & 0 deletions benchmark/ChildModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php
declare(strict_types = 1);

class ChildModel
{
protected $id;
/** @var string */
protected $name;
/** @var string */
protected $login;
/** @var DateTime */
protected $creAt;
/** @var bool */
protected $active;

public function __construct()
{
$this->creAt = new DateTime;
}

public function __toString(): string
{
return (string)$this->id;
}

public function getEmail(): string
{
return $this->email;
}

public function setEmail(string $email): void
{
$this->email = $email;
}

/** @var string */
protected $email;

public function getId()
{
return $this->id;
}

public function setId($id): void
{
$this->id = $id;
}

public function getName(): ?string
{
return $this->name;
}

public function setName(string $name): void
{
$this->name = $name;
}

public function getLogin(): ?string
{
return $this->login;
}

public function setLogin(string $login): void
{
$this->login = $login;
}

public function getCreAt(): DateTime
{
return $this->creAt;
}

public function setCreAt(DateTime $creAt): void
{
$this->creAt = $creAt;
}

public function isActive(): bool
{
return $this->active;
}

public function setActive(bool $active): void
{
$this->active = $active;
}

public function getCreAtTimestamp(): int
{
return $this->creAt->getTimestamp();
}

public function getTitleName(string $title): string
{
return $title . ' ' . $this->name;
}

public function setTitleName(string $name, string $suffix): void
{
$this->name = $name . ' ' . $suffix;
}
}
12 changes: 6 additions & 6 deletions benchmark/UserModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ class UserModel
protected $name;
/** @var string */
protected $login;
/** @var \DateTime */
/** @var DateTime */
protected $creAt;
/** @var bool */
protected $active;
/** @var UserModel|null */
protected $childModel;
/** @var ChildModel|null */
protected $child;

public function __construct()
{
$this->creAt = new \DateTime;
$this->creAt = new DateTime;
}

public function __toString(): string
Expand Down Expand Up @@ -68,12 +68,12 @@ public function setLogin(string $login): void
$this->login = $login;
}

public function getCreAt(): \DateTime
public function getCreAt(): DateTime
{
return $this->creAt;
}

public function setCreAt(\DateTime $creAt): void
public function setCreAt(DateTime $creAt): void
{
$this->creAt = $creAt;
}
Expand Down
14 changes: 8 additions & 6 deletions benchmark/bechmark-collections.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,27 @@

require_once __DIR__ .'/../vendor/autoload.php';
require_once 'UserModel.php';
require_once 'ChildModel.php';
$faker = Faker::create();

$iterations = $argv[1] ?? 1000;
$blackfire = $argv[2] ?? false;
$iterations++;

$service = new DataTransformer;
$service->getMapsManager()->setMapDir(UserModel::class, __DIR__);
$service->getMapsManager()->setMapDir(UserModel::class, __DIR__ . '/maps/' . UserModel::class);
$service->getMapsManager()->setMapDir(ChildModel::class, __DIR__ . '/maps/' . ChildModel::class);

$collectionDto = [];
while ($iterations--) {
$collectionDto[] = [
'id' => $faker->randomDigit,
'creAt' => $faker->unixTime(),
'name' => $faker->name,
'login' => $faker->name,
'name' => $faker->name(),
'login' => $faker->name(),
'active' => $faker->numberBetween(0, 2),
'email' => $faker->email,
'childModel' => [
'child' => [
'id' => $faker->randomDigit,
'creAt' => time(),
'name' => $faker->unixTime(),
Expand All @@ -46,8 +48,8 @@
$collectionDto = $service->toDtoCollection($models);

$diff = (microtime(true) - $startTime) * 1000;
echo sprintf('%2.3f ms', $diff);
echo "\n" . memory_get_peak_usage()/1024;
echo PHP_EOL . 'transformer: ' . sprintf('%2.3f ms', $diff);
echo PHP_EOL . memory_get_peak_usage()/1024;

if ($blackfire) {
$client->endProbe($probe);
Expand Down
6 changes: 4 additions & 2 deletions benchmark/bechmark.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@

require_once __DIR__ .'/../vendor/autoload.php';
require_once 'UserModel.php';
require_once 'ChildModel.php';
$faker = Faker::create();

$iterations = $argv[1] ?? 1000;
$blackfire = $argv[2] ?? false;
$iterations++;

$service = new DataTransformer;
$service->getMapsManager()->setMapDir(UserModel::class, __DIR__);
$service->getMapsManager()->setMapDir(UserModel::class, __DIR__ . '/maps/' . UserModel::class);
$service->getMapsManager()->setMapDir(ChildModel::class, __DIR__ . '/maps/' . ChildModel::class);

$collectionDto = [];
while ($iterations--) {
Expand All @@ -25,7 +27,7 @@
'login' => $faker->name,
'active' => $faker->numberBetween(0, 2),
'email' => $faker->email,
'childModel' => [
'child' => [
'id' => $faker->randomDigit,
'creAt' => time(),
'name' => $faker->unixTime(),
Expand Down
11 changes: 11 additions & 0 deletions benchmark/maps/ChildModel/dto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
declare(strict_types=1);

return [
'id' => [],
'creAt' => [],
'name' => [],
'login' => [],
'active' => [],
'email' => [],
];
4 changes: 2 additions & 2 deletions benchmark/dto.php → benchmark/maps/UserModel/dto.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
]
]
],
'childModel' => [
'child' => [
'ref' => [
'model' => 'UserModel',
'model' => 'ChildModel',
'map' => 'dto'
]
]
Expand Down
16 changes: 8 additions & 8 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 15 additions & 13 deletions src/DataTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace PTS\DataTransformer;

use PTS\Hydrator\HydratorService;
use function get_class;
use function is_callable;

class DataTransformer implements DataTransformerInterface
{
Expand All @@ -28,8 +30,8 @@ public function getMapsManager(): MapsManager
public function toModel(string $class, array $dto, string $mapName = 'dto'): object
{
$map = $this->mapsManager->getMap($class, $mapName);
$dto = $this->resolveRefPopulate($dto, $map['refs']);
$dto = $this->applyPipes($dto, $map['pipe']);
$dto = $map['refs'] ? $this->resolveRefPopulate($dto, $map['refs']) : $dto;
$dto = $map['pipe'] ? $this->applyPipes($dto, $map['pipe']) : $dto;
return $this->hydratorService->hydrate($dto, $class, $map['rules']);
}

Expand All @@ -39,8 +41,8 @@ public function toModelsCollection(string $class, array $dtoCollection, string $

$models = [];
foreach ($dtoCollection as $dto) {
$dto = $this->resolveRefPopulate($dto, $map['refs']);
$dto = $this->applyPipes($dto, $map['pipe']);
$dto = $map['refs'] ? $this->resolveRefPopulate($dto, $map['refs']) : $dto;
$dto = $map['pipe'] ? $this->applyPipes($dto, $map['pipe']) : $dto;
$models[] = $this->hydratorService->hydrate($dto, $class, $map['rules']);
}

Expand All @@ -49,9 +51,9 @@ public function toModelsCollection(string $class, array $dtoCollection, string $

public function fillModel(object $model, array $dto, string $mapName = 'dto'): object
{
$map = $this->mapsManager->getMap(\get_class($model), $mapName);
$dto = $this->resolveRefPopulate($dto, $map['refs']);
$dto = $this->applyPipes($dto, $map['pipe']);
$map = $this->mapsManager->getMap(get_class($model), $mapName);
$dto = $map['refs'] ? $this->resolveRefPopulate($dto, $map['refs']) : $dto;
$dto = $map['pipe'] ? $this->applyPipes($dto, $map['pipe']) : $dto;
$this->hydratorService->hydrateModel($dto, $model, $map['rules']);

return $model;
Expand All @@ -70,16 +72,16 @@ public function toDtoCollection(array $models, string $mapName = 'dto', array $o

public function toDTO(object $model, string $mapName = 'dto', array $options = []): array
{
$map = $this->mapsManager->getMap(\get_class($model), $mapName);
$map = $this->mapsManager->getMap(get_class($model), $mapName);
$excludeRules = $options['excludeFields'] ?? [];

foreach ($excludeRules as $name) {
unset($map['pipe'][$name], $map['rules'][$name], $map['refs'][$name]);
}

$dto = $this->hydratorService->extract($model, $map['rules']);
$dto = $this->applyPipes($dto, $map['pipe'], self::FILTER_TYPE_EXTRACT);
return $this->resolveRefExtract($dto, $map['refs']);
$dto = $map['pipe'] ? $this->applyPipes($dto, $map['pipe'], self::FILTER_TYPE_EXTRACT) : $dto;
return $map['refs'] ? $this->resolveRefExtract($dto, $map['refs']) : $dto;
}

protected function resolveRefExtract(array $dto, array $refsRules): array
Expand Down Expand Up @@ -116,7 +118,7 @@ protected function resolveRefPopulate(array $dto, array $refsRules): array
return $dto;
}

protected function applyPipes(array $dto, array $pipes, $type = self::FILTER_TYPE_POPULATE): array
protected function applyPipes(array $dto, array $pipes, string $type = self::FILTER_TYPE_POPULATE): array
{
$fieldsPipes = array_intersect_key($pipes, $dto);
foreach ($fieldsPipes as $name => $filters) {
Expand All @@ -127,10 +129,10 @@ protected function applyPipes(array $dto, array $pipes, $type = self::FILTER_TYP
return $dto;
}

protected function applyFilters($value, array $filters, $type)
protected function applyFilters($value, array $filters, string $type)
{
foreach ($filters as $filter) {
if (\is_callable($filter)) {
if (is_callable($filter)) {
$value = $filter($value);
continue;
}
Expand Down

0 comments on commit 6e5d65c

Please sign in to comment.