[TASK] Optimize speed for instantiating class with arguments 63/26363/6
authorHelmut Hummel <helmut.hummel@typo3.org>
Thu, 12 Dec 2013 21:44:42 +0000 (22:44 +0100)
committerStefan Neufeind <typo3.neufeind@speedpartner.de>
Sat, 14 Dec 2013 21:24:21 +0000 (22:24 +0100)
PHP reflection has quite an overhead in performance.
Use a switch construct like in Flow instead to
instantiate classes with up to 8 arguments without
reflection.

Resolves: #53682
Releases: 6.2, 6.1, 6.0
Change-Id: I82ecf0b1ea9a412a39b4429d7689f2bb6489f3df
Reviewed-on: https://review.typo3.org/26363
Reviewed-by: Philipp Gampe
Tested-by: Philipp Gampe
Reviewed-by: Markus Klein
Reviewed-by: Stefan Neufeind
Tested-by: Stefan Neufeind
typo3/sysext/core/Classes/Utility/GeneralUtility.php

index 84aceb1..7f87ccc 100644 (file)
@@ -4142,15 +4142,7 @@ Connection: close
                        return array_shift(self::$nonSingletonInstances[$finalClassName]);
                }
                // Create new instance and call constructor with parameters
-               if (func_num_args() > 1) {
-                       $constructorArguments = func_get_args();
-                       array_shift($constructorArguments);
-                       $reflectedClass = new \ReflectionClass($finalClassName);
-                       $instance = $reflectedClass->newInstanceArgs($constructorArguments);
-               } else {
-                       $fullyQualifiedClassName = '\\' . $finalClassName;
-                       $instance = new $fullyQualifiedClassName();
-               }
+               $instance = static::instantiateClass($finalClassName, func_get_args());
                // Create alias if not present
                $alias = \TYPO3\CMS\Core\Core\ClassLoader::getAliasForClassName($finalClassName);
                if ($finalClassName !== $alias && !class_exists($alias, FALSE)) {
@@ -4164,6 +4156,51 @@ Connection: close
        }
 
        /**
+        * Speed optimized alternative to ReflectionClass::newInstanceArgs()
+        *
+        * @param string $className
+        * @param array $arguments
+        * @return mixed
+        */
+       protected static function instantiateClass($className, $arguments) {
+               switch (count($arguments)) {
+                       case 1:
+                               $instance = new $className();
+                               break;
+                       case 2:
+                               $instance = new $className($arguments[1]);
+                               break;
+                       case 3:
+                               $instance = new $className($arguments[1], $arguments[2]);
+                               break;
+                       case 4:
+                               $instance = new $className($arguments[1], $arguments[2], $arguments[3]);
+                               break;
+                       case 5:
+                               $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4]);
+                               break;
+                       case 6:
+                               $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5]);
+                               break;
+                       case 7:
+                               $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6]);
+                               break;
+                       case 8:
+                               $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7]);
+                               break;
+                       case 9:
+                               $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7], $arguments[8]);
+                               break;
+                       default:
+                               $class = new \ReflectionClass($className);
+                               array_shift($arguments);
+                               $instance = $class->newInstanceArgs($arguments);
+                               return $instance;
+               }
+               return $instance;
+       }
+
+       /**
         * Returns the class name for a new instance, taking into account
         * registered implemetations for this class
         *