Performance of call_user_func_array . Why do libraries only use it with 5 arguments or more?

Asked

Viewed 188 times

1

Let’s discuss: These days I took a look at the source code of a Zendframework2 class. There was an implementation of the magic method __call. In that method there was something that caught my attention: The use of call_user_func_array was restricted only when the method being called had more than 4 arguments. Along with it was an English commentary, which I forgot which one is, which explains why.

To confirm that this was not my (or Zendframework’s) mistake, I went to take a look at the source code of the Laravel4 and came across the same thing (but without the comment specifying why).

See the code snippet:

public static function __callStatic($method, $args)
    {
        $instance = static::getFacadeRoot();
        if (! $instance) {
            throw new RuntimeException('A facade root has not been set.');
        }
        switch (count($args)) {
            case 0:
                return $instance->$method();
            case 1:
                return $instance->$method($args[0]);
            case 2:
                return $instance->$method($args[0], $args[1]);
            case 3:
                return $instance->$method($args[0], $args[1], $args[2]);
            case 4:
                return $instance->$method($args[0], $args[1], $args[2], $args[3]);
            default:
                return call_user_func_array([$instance, $method], $args);
        }
    }

Realize that the Laravel only considers using call_user_func_array if the call from __callStatic has the passage of 5 or more arguments.

Interestingly enough, I would personally consider it useless typing code, since the call_user_func_array would make the call of a method or function much more dynamic, but two known libraries did just the way it seemed most complex.

So I’d like to know what the reason is.

Is there a problem with loss of Performa (significantly) that induces frameworks to act in this way?

Is there a note from PHP itself that indicates this?

Note: Who wants to check the code, see here: https://github.com/illuminate/support/blob/master/Facades/Facade.php

  • Without any in-depth analysis I would begin by saying that this function iterates the method of the first array several times with the different values existing in the second array, that is, it maps the variables specified in the second member, in the method specified in the first member. Imagine having to map values with no need. Maybe that’s the general idea. Just like you said it’s a useless typing, calculate the total of arguments, and pass these references without making use of the user_func_array, the same would say for the script to map 2 parameters using this function.

  • Even more, since frameworks are designed to operate as small and large applications, decreasing the time it takes for the script to execute a command and generate the response is crucial whenever possible.

  • A new information: The function call_user_func_array is 15 times slower than a common function call. If this is called often (as in the case of the Facade class that uses this Facade class almost in every application) it could be bad

  • 2

    Exactly, as I said above, imagine having to map 2 values and take longer than necessary when you can do it directly in the intended method. Now, with about 5 arguments or more, the response time would be identical or even shorter than passing them directly in the method itself. But you wouldn’t have to write conditions for each.

1 answer

1

Answering your question. Yes is slower.

That one question similar to yours in Stackoverflow gringo has as one of the answers that the call is 15 times slower using call_user_func_array but nay put references to how it came to that number.

I kept looking for answers until I found this post that actually does an analysis regarding the speed of direct calls or using this function.

He comes to the conclusion that call_user_func is twice as slow and call_user_func_array is 10-20% slower than call_user_func.

I couldn’t find any official PHP information. However, remember that whoever is behind PHP and Zendframework is the same organization as Zend, so if they use this code it is not useless typing.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.