Commit 5c8081ad authored by Helmut Hummel's avatar Helmut Hummel Committed by Stefan Neufeind
Browse files

[TASK] Optimize speed for instantiating class with arguments

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, 4.7, 4.5
Change-Id: I8ab21fa5ae609fc4653205f4b53c51ed61618ea7
Reviewed-on: http://review.typo3.org/33308


Reviewed-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: default avatarMarkus Klein <klein.t3@reelworx.at>
Tested-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: default avatarStefan Neufeind <typo3.neufeind@speedpartner.de>
Tested-by: default avatarStefan Neufeind <typo3.neufeind@speedpartner.de>
parent 9bae63e5
......@@ -5429,15 +5429,7 @@ final class t3lib_div {
}
// 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 {
$instance = new $finalClassName;
}
$instance = self::instantiateClass($finalClassName, func_get_args());
// Register new singleton instance
if ($instance instanceof t3lib_Singleton) {
......@@ -5462,6 +5454,54 @@ final class t3lib_div {
return (class_exists($className) && class_exists('ux_' . $className, FALSE) ? self::makeInstanceClassName('ux_' . $className) : $className);
}
/**
* Speed optimized alternative to ReflectionClass::newInstanceArgs()
*
* @param string $className Name of the class to instantiate
* @param array $arguments Arguments passed to self::makeInstance() thus the first one with index 0 holds the requested class name
* @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:
// The default case for classes with constructors that have more than 8 arguments.
// This will fail when one of the arguments shall be passed by reference.
// In case we really need to support this edge case, we can implement the solution from here: https://review.typo3.org/26344
$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 the
* class-extension API.
......
......@@ -847,9 +847,10 @@ class tslib_cObj {
$name = $classMapping[$name];
if (!array_key_exists($name, $this->contentObjects)) {
try {
$this->contentObjects[$name] = t3lib_div::makeInstance('tslib_content_' . $name, $this);
} catch (ReflectionException $e) {
$fullyQualifiedClassName = 'tslib_content_' . $name;
if (class_exists($fullyQualifiedClassName)) {
$this->contentObjects[$name] = t3lib_div::makeInstance($fullyQualifiedClassName, $this);
} else {
$this->contentObjects[$name] = NULL;
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment