9

In magento 2 the classes are instantiated using an object manager factory: \Magento\Framework\ObjectManager\Factory\Factory::create().
So far so goo. But there is something that I don't understand here.
After checking if there are no circular references in the arguments that should be passed to the constructor for DI and after the arguments are determined there is this ($args are the arguments that should be passed to the constructor):

    switch (count($args)) {
        case 1:
            return new $type($args[0]);
        case 2:
            return new $type($args[0], $args[1]);
        case 3:
            return new $type($args[0], $args[1], $args[2]);
        case 4:
            return new $type($args[0], $args[1], $args[2], $args[3]);
        case 5:
            return new $type($args[0], $args[1], $args[2], $args[3], $args[4]);
        case 6:
            return new $type($args[0], $args[1], $args[2], $args[3], $args[4], $args[5]);
        case 7:
            return new $type($args[0], $args[1], $args[2], $args[3], $args[4], $args[5], $args[6]);
        case 8:
            return new $type($args[0], $args[1], $args[2], $args[3], $args[4], $args[5], $args[6], $args[7]);
        default:
            $reflection = new \ReflectionClass($type);
            return $reflection->newInstanceArgs($args);
    }

Why is this long switch statement? Why not use directly the code from the default branch?
Or why stop the case at 8? Why not 5 or 10 or 127?

  • very bed coding – Keyul Shah Sep 3 '14 at 14:01
  • 1
    @KeyulShah. Could be, but I'm almost sure there is a reason behind this. – Marius Sep 3 '14 at 14:03
11

The reason is performance. Instantiation through new is slightly faster than reflection. Most classes have less than 8 arguments so this switch covers most cases.

Maybe it'll be removed.

  • 1
    Thanks for the answer. I must say I'm a little disappointed. I was expecting something fancy. :) – Marius Sep 3 '14 at 14:24
  • 1
    Performance is not good enough reason? :) – Anton Kril Sep 3 '14 at 14:26
  • 3
    Also, in case it's not clear from the answer, a slightly faster implementation in something that happens a lot (i.e. instantiating an object) is well worth it. – Alan Storm Sep 3 '14 at 14:28
  • 1
    @AntonKril. I wasn't talking about the reasons. I was hoping for a fancy answer like "Because we do it this way, your beer will never get warm" or something like that. But I guess "performance" will do it for now. Stay close please. other philosophical questions will follow in the next days. :) – Marius Sep 3 '14 at 14:33
6

The performance gain is almost invisible. When I try to instantiate 1000000 objects with the 2 methods, here is the result :

enter image description here

I'm using Magento 2 Beta and PHP version (see below)

PHP 5.6.12-1+deb.sury.org~trusty+1 (cli) Copyright (c) 1997-2015 The PHP Group Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies with Xdebug v2.3.2, Copyright (c) 2002-2015, by Derick Rethans

In order to make this test, I used this script

  • Well...Anton said is "slightly faster". Which it is :). But anyway...+1 for the profiling. – Marius Sep 15 '15 at 8:21
  • This code was added long time ago. It was tested on PHP 5.3 On later versions difference became less visible that's why I mentioned in my answer that this code might be removed later. – Anton Kril Jan 16 '16 at 16:05
  • @AntonKril Instead, you pumped it up to 15 parameters? ;-) – Fabian Schmengler Apr 20 '16 at 10:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.