Based on another question

Question in the context of PHP 5.5+ and 7

There is a script, a kind of orchestrator, which, depending on the input parameters, instantiates different classes.

I know three fundamentally different approaches for implementation.

The first:

switch ($method) { case 'login': $call = new Login($data); break; case 'list': $call = new List($data); break; default: $call = new WrongMethod($data); } 

Second:

 $methods = [ 'login' => 'Login', 'list' => 'GetList', ]; $className = isset($methods[ $method ]) ? $methods[ $method ] : 'WrongMethod'; $call = new $className($data); 

Third (proposed by Dmitriy Simushev):

 $methods = [ 'login' => Login::class, 'list' => GetList::class, ]; $className = isset($methods[ $method ]) ? $methods[ $method ] : WrongMethod::class; $call = new $className($data); 

What can you say for the disposal of memory and the speed of each of them? (I suspect that by memory will win the second, but I can not prove)

  • There is only one reliable way - to profile and make a benchmark. Or do you want to do it for you? - KoVadim
  • @KoVadim is a much more reliable way - to know how the php compiler works. Actually a question to those who know. Well, either to those who have already asked similar questions, profiled and made benchmarks. - rjhdby
  • No, this method is not more reliable, because there are very few such people. There are many people who think they know, but they are mistaken. But, firstly, there is an interpreter, and secondly, it can work on different hardware and different versions of php in different ways. Are you sure that you do not want to profile / benchmark? - KoVadim
  • @KoVadim In general, there is a compiler in the bytecode that is already interpreted. IMHO my question is more related to the first part of this process, that is, compilation. The question for me personally at the moment is purely academic. If there are no experts, then it is possible. - rjhdby
  • in any interpreter, one way or another, there is a conversion to a convenient representation. But it still does not give the language to be compiled :) If you are too lazy to do benchmarks - go to the site 3v4l.org - there you can enter your example and look at it "deeper". - KoVadim

2 answers 2

I would suggest a little other option to call respectively the method

 'login' => 'Login' 'getList' => 'GetList' 

and so install

 $className = ucfirst($method); if(class_exists($className)) { new $className($data); } else { new WrongMethod($data); } 

According to the complexity theory of the algorithms, all 3-ris of the above method are the same as the one given by me.

  • As far as I understand, using class_exists with autoload and namespaces is still fun. Yes, and to maintain an exact link "method name" == "class name", also imposes some restrictions on the back that is on the front. - rjhdby
  • To be honest, in any case, the automatic instance of the class is not very much so, it is not obvious which class is in front of you at any time of the program. - Naumov

Conducted the following experiment.

Created 4 identical classes A, B, C, D. This type:

 class A { private $b; public function __construct() { for($i=0;$i<100000;$i++) $b[] = $i; } } 

And the orchestrator:

 spl_autoload_register( function ($class) { include_once($class . ".php"); } ); $start = microtime(true); //Тут пример только одного из вариантов, что бы было представление о структуре скрипта $map = [ '1' => 'A', '2' => 'B', '3' => 'C', '4' => 'D' ]; $m = (string)rand(1, 4); $a = new $map[$m](); echo "Time: " . (microtime(true) - $start) . "s<br>"; echo "RAM script usage: " . (memory_get_peak_usage(false) / 1024 / 1024) . " MiB<br>"; echo "RAM allocated: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MiB<br>"; var_dump(preg_grep("/^.$/",get_declared_classes())); 

Launched each of the options several times, warming up for the sake of.

Actually, on all three options, the picture is on average the same.

 Time: 0.093303s RAM script usage: 14.208557128906 MiB RAM allocated: 14.5 MiB array (size=1) 133 => string 'B' (length=1) 

Only one class is actually loaded, the one that falls into the execution branch.