-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimize creation from constructor #186
Optimize creation from constructor #186
Conversation
I also thought about removing hasConstructorArgument check because just calling getConstructorArgument would be faster, but that's technically changing this behavior: readonly class Dto
{
public function __construct(
public ?string $optionalNullableString = 'default'
) {}
}
$data = [];
$object = $autoMapper->map($data, Dto::class, [MapperContext::CONSTRUCTOR_ARGUMENTS => [
Dto::class => ['optionalNullableString' => null]
]]);
$object->optionalNullableString === null; // with hasConstructorArgument check
$object->optionalNullableString === 'default'; // without hasConstructorArgument check Maybe there should be a test for this behavior🤔. I can add it to this PR |
f425123
to
94377bf
Compare
Hi @MrMeshok nice PR, very good idea!
won't that even create an error if you have this kind of readonly class Dto
{
public function __construct(
public ?string $optionalNullableString
) {}
} if we want to allow
this should definitely be tested, maybe in the version without the default value in the argument |
Just tested it, it's just creates $constructarg = $source['propertyName']
?? \AutoMapper\MapperContext::getConstructorArgument($context, 'Dto', 'propertyName') // returns null
?? null; You can emulate that happens if hasConstructorArgument check gets removed by replacing array_key_exists by isset in method implementation public static function hasConstructorArgument(array $context, string $class, string $key): bool
{
return isset($context[self::CONSTRUCTOR_ARGUMENTS][$class][$key]);
// return \array_key_exists($key, $context[self::CONSTRUCTOR_ARGUMENTS][$class] ?? []);
}
I personally think that's a very niche feature, and I had to think very hard to come up with an example where it could matter. |
I thought about it over the weekend, there is a way to use |
When object gets created from constructor, there are always checks for constructor arguments in context. This eats some of performance, especially if you don't use context. When looking at the generated code, I noticed that it can be optimized a little.
I didn't benchmark it a lot, but I did see around 10% more performance with this optimization
Comparisons
Argument from source
Before:
After:
Argument from source with array transformer
Before:
After:
Argument without source
Before and After here logically the same, I just changed it so code would be consistent with arguments from source.
Before:
After: