diff --git a/CHANGELOG.md b/CHANGELOG.md
index 27144d1..79db6d8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - [GH#184](https://github.com/jolicode/automapper/pull/184) Fix error when mapping from stdClass to constructor with nullable/optional arguments
 - [GH#185](https://github.com/jolicode/automapper/pull/185) Fix constructor with default parameter array does not work with constructor_arguments context
 
+### Changed
+- [GH#186](https://github.com/jolicode/automapper/pull/186) Optimize creation from constructor
+
 ## [9.1.2] - 2024-09-03
 ### Fixed
 - [GH#174](https://github.com/jolicode/automapper/pull/174) Fix race condition when writing generated mappers
diff --git a/src/Generator/CreateTargetStatementsGenerator.php b/src/Generator/CreateTargetStatementsGenerator.php
index be8fa27..000383a 100644
--- a/src/Generator/CreateTargetStatementsGenerator.php
+++ b/src/Generator/CreateTargetStatementsGenerator.php
@@ -126,19 +126,19 @@ private function constructorArguments(GeneratorMetadata $metadata): array
             // Find property for parameter
             $propertyMetadata = $metadata->getTargetPropertyWithConstructor($constructorParameter->getName());
 
-            $createObjectStatement = null;
+            $propertyStatements = null;
             $constructArgument = null;
             $constructorName = null;
 
             if (null !== $propertyMetadata) {
-                [$createObjectStatement, $constructArgument, $constructorName] = $this->constructorArgument($metadata, $propertyMetadata, $constructorParameter);
+                [$propertyStatements, $constructArgument, $constructorName] = $this->constructorArgument($metadata, $propertyMetadata, $constructorParameter);
             }
 
-            if (null === $createObjectStatement || null === $constructArgument || null === $constructorName) {
-                [$createObjectStatement, $constructArgument, $constructorName] = $this->constructorArgumentWithoutSource($metadata, $constructorParameter);
+            if (null === $propertyStatements || null === $constructArgument || null === $constructorName) {
+                [$propertyStatements, $constructArgument, $constructorName] = $this->constructorArgumentWithoutSource($metadata, $constructorParameter);
             }
 
-            $createObjectStatements[] = $createObjectStatement;
+            $createObjectStatements = [...$createObjectStatements, ...$propertyStatements];
             $constructArguments[$constructorName] = $constructArgument;
         }
 
@@ -158,17 +158,18 @@ private function constructorArguments(GeneratorMetadata $metadata): array
     }
 
     /**
-     * Check if there is a constructor argument in the context, otherwise we use the transformed value.
+     * If source missing a constructor argument, check if there is a constructor argument in the context, otherwise we use the default value or throw exception.
      *
      * ```php
-     *  if (MapperContext::hasConstructorArgument($context, $target, 'propertyName')) {
-     *     $constructArg1 = $source->propertyName ?? MapperContext::getConstructorArgument($context, $target, 'propertyName');
-     *  } else {
-     *     $constructArg1 = $source->propertyName;
-     *  }
+     *  {transformation of value}
+     *  $constructarg = $value ?? (
+     *      MapperContext::hasConstructorArgument($context, $target, 'propertyName')
+     *          ? MapperContext::getConstructorArgument($context, $target, 'propertyName')
+     *          : {defaultValueExpr} // default value or throw exception
+     *  )
      * ```
      *
-     * @return array{Stmt, Arg, string}|array{null, null, null}
+     * @return array{Stmt[], Arg, string}|array{null, null, null}
      */
     private function constructorArgument(GeneratorMetadata $metadata, PropertyMetadata $propertyMetadata, \ReflectionParameter $parameter): array
     {
@@ -218,45 +219,39 @@ private function constructorArgument(GeneratorMetadata $metadata, PropertyMetada
         }
 
         return [
-            new Stmt\If_(new Expr\StaticCall(new Name\FullyQualified(MapperContext::class), 'hasConstructorArgument', [
-                new Arg($variableRegistry->getContext()),
-                new Arg(new Scalar\String_($metadata->mapperMetadata->target)),
-                new Arg(new Scalar\String_($propertyMetadata->target->property)),
-            ]), [
-                'stmts' => [
-                    ...$propStatements,
-                    new Stmt\Expression($argumentAssignClosure(new Expr\StaticCall(new Name\FullyQualified(MapperContext::class), 'getConstructorArgument', [
-                        new Arg($variableRegistry->getContext()),
-                        new Arg(new Scalar\String_($metadata->mapperMetadata->target)),
-                        new Arg(new Scalar\String_($propertyMetadata->target->property)),
-                    ]))),
-                ],
-                'else' => new Stmt\Else_([
-                    ...$propStatements,
-                    new Stmt\Expression($argumentAssignClosure($defaultValueExpr)),
-                ]),
-            ]),
+            [
+                ...$propStatements,
+                new Stmt\Expression($argumentAssignClosure(
+                    new Expr\Ternary(
+                        new Expr\StaticCall(new Name\FullyQualified(MapperContext::class), 'hasConstructorArgument', [
+                            new Arg($variableRegistry->getContext()),
+                            new Arg(new Scalar\String_($metadata->mapperMetadata->target)),
+                            new Arg(new Scalar\String_($propertyMetadata->target->property)),
+                        ]),
+                        new Expr\StaticCall(new Name\FullyQualified(MapperContext::class), 'getConstructorArgument', [
+                            new Arg($variableRegistry->getContext()),
+                            new Arg(new Scalar\String_($metadata->mapperMetadata->target)),
+                            new Arg(new Scalar\String_($propertyMetadata->target->property)),
+                        ]),
+                        $defaultValueExpr,
+                    ),
+                )),
+            ],
             new Arg($constructVar, name: new Identifier($parameter->getName())),
             $parameter->getName(),
         ];
     }
 
     /**
-     * Check if there is a constructor argument in the context, otherwise we use the default value.
+     * Check if there is a constructor argument in the context, otherwise we use the default value or throw exception.
      *
-     * ```
-     * if (MapperContext::hasConstructorArgument($context, $target, 'propertyName')) {
-     *     $constructArg2 = MapperContext::getConstructorArgument($context, $target, 'propertyName');
-     * } else {
-     *     $constructArg2 = 'default value';
-     *     // or set to null if the parameter is nullable
-     *     $constructArg2 = null;
-     *     // throw an exception otherwise
-     *     throw new MissingConstructorArgumentsException('Cannot create an instance of "Foo" from mapping data because its constructor requires the following parameters to be present : "$propertyName".', 0, null, ['propertyName'], 'Foo');
-     * }
+     * ```php
+     *  $constructarg = MapperContext::hasConstructorArgument($context, $target, 'propertyName')
+     *      ? MapperContext::getConstructorArgument($context, $target, 'propertyName')
+     *      : {defaultValueExpr} // default value or throw exception
      * ```
      *
-     * @return array{Stmt, Arg, string}
+     * @return array{Stmt[], Arg, string}
      */
     private function constructorArgumentWithoutSource(GeneratorMetadata $metadata, \ReflectionParameter $constructorParameter): array
     {
@@ -274,28 +269,29 @@ private function constructorArgumentWithoutSource(GeneratorMetadata $metadata, \
         ]));
 
         if ($constructorParameter->isDefaultValueAvailable()) {
-            $defaultValueExpr = new Expr\Assign($constructVar, $this->getValueAsExpr($constructorParameter->getDefaultValue()));
+            $defaultValueExpr = $this->getValueAsExpr($constructorParameter->getDefaultValue());
         } elseif ($constructorParameter->allowsNull()) {
-            $defaultValueExpr = new Expr\Assign($constructVar, new Expr\ConstFetch(new Name('null')));
+            $defaultValueExpr = new Expr\ConstFetch(new Name('null'));
         }
 
         return [
-            new Stmt\If_(new Expr\StaticCall(new Name\FullyQualified(MapperContext::class), 'hasConstructorArgument', [
-                new Arg($variableRegistry->getContext()),
-                new Arg(new Scalar\String_($metadata->mapperMetadata->target)),
-                new Arg(new Scalar\String_($constructorParameter->getName())),
-            ]), [
-                'stmts' => [
-                    new Stmt\Expression(new Expr\Assign($constructVar, new Expr\StaticCall(new Name\FullyQualified(MapperContext::class), 'getConstructorArgument', [
-                        new Arg($variableRegistry->getContext()),
-                        new Arg(new Scalar\String_($metadata->mapperMetadata->target)),
-                        new Arg(new Scalar\String_($constructorParameter->getName())),
-                    ]))),
-                ],
-                'else' => new Stmt\Else_([
-                    new Stmt\Expression($defaultValueExpr),
-                ]),
-            ]),
+            [
+                new Stmt\Expression(new Expr\Assign($constructVar,
+                    new Expr\Ternary(
+                        new Expr\StaticCall(new Name\FullyQualified(MapperContext::class), 'hasConstructorArgument', [
+                            new Arg($variableRegistry->getContext()),
+                            new Arg(new Scalar\String_($metadata->mapperMetadata->target)),
+                            new Arg(new Scalar\String_($constructorParameter->getName())),
+                        ]),
+                        new Expr\StaticCall(new Name\FullyQualified(MapperContext::class), 'getConstructorArgument', [
+                            new Arg($variableRegistry->getContext()),
+                            new Arg(new Scalar\String_($metadata->mapperMetadata->target)),
+                            new Arg(new Scalar\String_($constructorParameter->getName())),
+                        ]),
+                        $defaultValueExpr,
+                    ))
+                ),
+            ],
             new Arg($constructVar, name: new Identifier($constructorParameter->getName())),
             $constructorParameter->getName(),
         ];