All Projects → fab2s → call_user_func

fab2s / call_user_func

Licence: other
A benchmark study of call_user_func()

Programming Languages

PHP
23972 projects - #3 most used programming language

Projects that are alternatives of or similar to call user func

Sre Interview Prep Guide
Site Reliability Engineer Interview Preparation Guide
Stars: ✭ 2,446 (+12773.68%)
Mutual labels:  study
Virgilio
Virgilio is developed and maintained by these awesome people. You can email us virgilio.datascience (at) gmail.com or join the Discord chat.
Stars: ✭ 13,200 (+69373.68%)
Mutual labels:  study
Mindforger Repository
MindForger documentation repository.
Stars: ✭ 221 (+1063.16%)
Mutual labels:  study
Studynotes.org
✏️ Learn faster. Study better.
Stars: ✭ 142 (+647.37%)
Mutual labels:  study
Cehv10 Notes
📕 Both personal and public notes for EC-Council's CEHv10 312-50, because its thousands of pages/slides of boredom, and a braindump to many
Stars: ✭ 170 (+794.74%)
Mutual labels:  study
Websites And Tools
🔰 分类收藏一些网站、工具和软件,记录一些关于 windows/macOS/linux 系统的使用技巧和软件操作。
Stars: ✭ 196 (+931.58%)
Mutual labels:  study
Mindforger
Thinking notebook and Markdown editor.
Stars: ✭ 1,695 (+8821.05%)
Mutual labels:  study
cmil
CMIL - Clarified Multilingual Intermediate Language
Stars: ✭ 32 (+68.42%)
Mutual labels:  study
Tamburetei
Fazendo de tamburete as cadeiras de [email protected]
Stars: ✭ 177 (+831.58%)
Mutual labels:  study
Flutter Study
Flutter Study
Stars: ✭ 2,441 (+12747.37%)
Mutual labels:  study
Study Reinforcement Learning
Studying Reinforcement Learning Guide
Stars: ✭ 147 (+673.68%)
Mutual labels:  study
Gank.lu
Gank.io client for iOS
Stars: ✭ 161 (+747.37%)
Mutual labels:  study
My Notes
📝 Just a repo with my study notes. A simple notebook
Stars: ✭ 196 (+931.58%)
Mutual labels:  study
Big Data Study
🐳 big data study
Stars: ✭ 141 (+642.11%)
Mutual labels:  study
Demo Laravel Zhihu Over
laravel study
Stars: ✭ 244 (+1184.21%)
Mutual labels:  study
Uexam Mysql
学之思在线考试系统,支持多种题型:选择题、多选题、判断题、填空题、解答题以及数学公式,包含PC端、小程序端,扩展性强,部署方便、界面设计友好、代码结构清晰
Stars: ✭ 124 (+552.63%)
Mutual labels:  study
Live Video Study Notes
📺 整理前端视频直播相关技术的笔记,适合想入门前端流媒体技术的人阅读
Stars: ✭ 192 (+910.53%)
Mutual labels:  study
spring-study-sprout
🌱 11번가 새싹 신입들의 스프링 정복기 🚀
Stars: ✭ 180 (+847.37%)
Mutual labels:  study
AlgoSSAFY
삼성 청년 SW 아카데미 4기 서울 알고리즘 스터디 🔥🧑‍💻🔥
Stars: ✭ 14 (-26.32%)
Mutual labels:  study
Vocabhunter
VocabHunter helps learners of foreign languages find vital new vocabulary to study.
Stars: ✭ 201 (+957.89%)
Mutual labels:  study

call_user_func

call_user_func() and call_user_func_array() are often mentioned as "slow". At some point I needed to know by how much this could impact processes involving very large amount of Callable calls.

The problem

A Callable can be of many forms, either a string, an array a lambda or a Closure. If you want to generically call a Callable, the easy path is to just call call_user_func() :

$result = call_user_func($callable);

or call_user_func_array() :

$result = call_user_func_array($callable);

This has the great advantage of simplicity, but unfortunately, it is slower than direct invocation. This one liner also hides some complexity as each Callable type will need it's own invocation method. If we where to do it manually, we would use something like :

if (is_string($callable)) {
    $callable = trim($callable, '\\');
    if (strpos($callable, '::')) {
        list($class, $method) = explode('::', $callable);
        $class::$method();
    } else {
        $callable();
    }
} else if (is_array($callable)) {
    $instance = current($callable);
    $method   = next($callable);
    $instance->$method();
} else {
    $callable();
}

Someone with more attention to estheticism could end up with a "smarter" solution using a simple "Closure Factory" :

/**
 *
 * @param Callable $callable
 * @return \Closure
 */
function closureFactory(Callable $callable)
{
    if (is_string($callable)) {
        $callable = trim($callable, '\\');
        if (strpos($callable, '::')) {
            list($class, $method) = explode('::', $callable);
            return function () use ($class, $method) {
                return $class::$method();
            };
        } else {
            return function () use ($callable) {
                return $callable();
            };
        }
    } else if (is_array($callable)) {
        return function () use ($callable) {
            return $callable[0]->$callable[1]();
        };
    } else {
        return function () use ($callable) {
            return $callable();
        };
    }
}

wich would later allow things like :

$closure = closureFactory($callable);
$result  = $closure();

In addition to being better organized, it allows reuse of the call for no additional cost, except reassigning in object context without php7 since calling :

$instance->closure = closureFactory($callable);
$result            = $instance->closure();

will not work and :

$instance->closure = closureFactory($callable);
$result            = ($instance->closure)();

will only work with php7. Bellow that you're stuck with :

$instance->closure = closureFactory($callable);
$closure           = $instance->closure;
$result            = $closure();

wich brings a bit of overhead and complexity.

Finding out

Exploring the options, I came up with a silly class, "Invoke", which wraps the Callable into a specialized class carrying the "fastest" invocation method. It seems insane at first because doing this involve wrapping the call into a class method, and in several cases, manipulating variables upon each call.

Invoke comes with a factory providing with the "best" instance for each Callable type :

$Invoker = InvokeFactory::create($callable);
// ...
$Invoker->exec($param);

Benchmarking

Of course, benchmarking does not tell everything and some benchmarks may even fail to prove the truth. In this case, I just timed the time taken to execute a number of calls of each recipe, and averaged over another number. Default for each test is 100 000 iterations averaged over 10 consecutive run (of 100k iteration each). It's not perfect by nature, as many thing happens in a modern computer, but you can use bigger number to tend to better results.

If you wish to try, clone the repo and run

$ composer install --dev

Then the benchmark can be run using the ./bench script :

$ php bench

You can additionally set the number of iteration and average rounds :

$ php bench --help
bench usage
no options  :   run with default iteration (100 000) and default average rounds (10)
options     :
    -i=[0-9]    Number of iterations. Each test will run this many time
    -a=[0-9]    Compute an average over this many test. Each test will execute
                execute all its iterations this many time.

The idea is to compare each case with various ways of calling the Callable. Since the primary goal was to compare invocation times, the dummy function/method/static/lambda/closure are all following the same synopsis :

function ($param) {
    return $param;
}

As the first results started to show, I added an even sillier test case which does the same thing as Invoke except it ends up calling call_user_func() instead of trying to be efficient. The idea behind it is to get an estimate of Invoke own overhead, since :

invoke_time ~= invoke_overhead + recipe_exec_time

which when :

recipe_exec_time ~= call_user_func_time

tells us

invoke_overhead ~= invoke_time - call_user_func_time

Again, it's not math, it's benchmarking ^^

I ran test against both closure factory and assigned closure factory to measure the cost of closure assignment at run-time.

Callable tested

With $param explicitly set to null before benchmark starts

  • Instance

    $instance = [$instance, 'method'];
  • Static

    $static = 'ClassName::method';
  • Function

    $function = 'functionName';
  • Lambda

    $lambda = function($param) {
         return $param;
    };
  • Closure

    With $use explicitly set to null before benchmark starts

    $closure = function($param) use ($use) {
        return $param;
    };

Invocation tested

  • call_user_func

    // in test loop
    call_user_func($callable, $param);
  • call_user_func_array

    // in test loop
    call_user_func_array($callable, $arrayParam);
  • directFunction

    // in test loop
    fucntionName($param);
  • directStatic

    // in test loop
    ClassName::method($param);
  • directInstance

    // in test loop
    $instance->method($param);
  • directLambda

    // in test loop
    $lambda($param);
  • directClosure

    // in test loop
    $closure($param);
  • ClosureFactory

    // before test loop
    $closure = ClosureFactory::create($callable);
    // in test loop
    $closure($param);
  • assignedClosureFactory

    // before test loop
    $closure = ClosureFactory::create($callable);
    // in test loop
    $call = $closure;
    $call($param);
  • directImplementation

    // in test loop
    if (is_string($callable)) {
        $callable = trim($callable, '\\');
        if (strpos($callable, '::')) {
            list($class, $method) = explode('::', $callable);
            $class::$method($param);
        } else {
            $callable($param);
        }
    } else if (is_array($callable)) {
        $class = $callable[0];
        $method = $callable[1];
        $class->{$method}($param);
    } else {
        $callable($param);
    }
  • Invoke

    // before test loop
    $instance = InvokeFactory::create($callable);
    // in test loop
    $instance->execOneArg($param);
  • InvokeCallUserFunc

    // before test loop
    $instance = new InvokeCallUserFunc($callable);
    // in test loop
    $instance->execOneArg($param);

Conclusion

First thing to note is that call_user_func() has been improved a lot with php7. It's about 3x faster average with 7.1.2 compared with 5.6.30. With 5.6.30, call_user_func almost always looses against Invoke, which in itself is interesting, especially if we evaluate Invoke's own overhead comparing with InvokeCallUserFunc case. call_user_func_array() is always slower than call_user_func(), which is not a surprise, but again, it is much slower with 5.6.30.

Of course, if you think about real world scenario, if 60% slower is significant, looking at timings show we're talking about fractions of a second every million call, with each million call costing around half a second. I can't think of many use cases where one would need to call millions of functions to build a web page, and few background process would actually loose so much with this 0.3 second lost every million call.

So as a practical conclusion, using call_user_func() is perfectly sane, even with php 5.6.30 (I did not tested bellow that).

Analyzing further, some interesting things to note are :

  • The few ifs of a direct implementation are costing too much
  • closure factory is surprisingly slow
  • assigned closure factory is as expected a bit slower than simple closure factory, but it's not very significant
  • php7 is a lot faster, with a bit more ram usage, but this should not actually matter since php7 has way better ram handling / sharing overall
  • Not much difference between php 7.1 and 7.2

Results

Test ran on win10 with Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz

PHP 5.6.30

$ php bench
Benchmarking call_user_func
Iterations: 100 000
Averaged over: 10
PHP 5.6.30 (cli) (built: Jan 18 2017 19:47:28)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
Windows NT 10.0 build 14393 (Windows 10) AMD64

instance ~ [$instance, 'method']
+------------------------+----------+-----------+--------+
| Invocation             | Time (s) | Delta (s) | %      |
+------------------------+----------+-----------+--------+
| directInstance         | 0.0116   | -0.0168   | -59.13 |
| call_user_func         | 0.0284   |           |        |
| Invoke                 | 0.0301   | +0.0017   | +6.11  |
| ClosureFactory         | 0.0370   | +0.0086   | +30.13 |
| directImplementation   | 0.0371   | +0.0087   | +30.48 |
| assignedClosureFactory | 0.0377   | +0.0093   | +32.83 |
| call_user_func_array   | 0.0393   | +0.0109   | +38.29 |
| InvokeCallUserFunc     | 0.0395   | +0.0111   | +39.26 |
+------------------------+----------+-----------+--------+

static ~ 'Class::method'
+------------------------+----------+-----------+---------+
| Invocation             | Time (s) | Delta (s) | %       |
+------------------------+----------+-----------+---------+
| directStatic           | 0.0098   | -0.0270   | -73.38  |
| Invoke                 | 0.0331   | -0.0037   | -10.03  |
| call_user_func         | 0.0367   |           |         |
| ClosureFactory         | 0.0396   | +0.0029   | +7.84   |
| assignedClosureFactory | 0.0400   | +0.0033   | +8.99   |
| call_user_func_array   | 0.0463   | +0.0095   | +25.97  |
| InvokeCallUserFunc     | 0.0496   | +0.0129   | +35.02  |
| directImplementation   | 0.0942   | +0.0575   | +156.46 |
+------------------------+----------+-----------+---------+

function ~ 'function'
+------------------------+----------+-----------+--------+
| Invocation             | Time (s) | Delta (s) | %      |
+------------------------+----------+-----------+--------+
| directFunction         | 0.0089   | -0.0230   | -72.03 |
| Invoke                 | 0.0261   | -0.0058   | -18.25 |
| ClosureFactory         | 0.0281   | -0.0039   | -12.15 |
| assignedClosureFactory | 0.0296   | -0.0024   | -7.53  |
| call_user_func         | 0.0320   |           |        |
| call_user_func_array   | 0.0416   | +0.0097   | +30.23 |
| InvokeCallUserFunc     | 0.0442   | +0.0122   | +38.31 |
| directImplementation   | 0.0521   | +0.0201   | +62.96 |
+------------------------+----------+-----------+--------+

lambda ~ function($param) { return $param }
+------------------------+----------+-----------+--------+
| Invocation             | Time (s) | Delta (s) | %      |
+------------------------+----------+-----------+--------+
| directLambda           | 0.0109   | -0.0135   | -55.15 |
| Invoke                 | 0.0226   | -0.0018   | -7.30  |
| ClosureFactory         | 0.0243   | -0.0001   | -0.40  |
| call_user_func         | 0.0244   |           |        |
| directImplementation   | 0.0251   | +0.0007   | +2.91  |
| assignedClosureFactory | 0.0263   | +0.0019   | +7.59  |
| call_user_func_array   | 0.0342   | +0.0098   | +40.09 |
| InvokeCallUserFunc     | 0.0356   | +0.0112   | +45.93 |
+------------------------+----------+-----------+--------+

closure ~ function($param) use($use) { return $param }
+------------------------+----------+-----------+--------+
| Invocation             | Time (s) | Delta (s) | %      |
+------------------------+----------+-----------+--------+
| directClosure          | 0.0150   | -0.0135   | -47.51 |
| call_user_func         | 0.0285   |           |        |
| ClosureFactory         | 0.0288   | +0.0003   | +1.20  |
| Invoke                 | 0.0289   | +0.0004   | +1.31  |
| directImplementation   | 0.0289   | +0.0004   | +1.50  |
| assignedClosureFactory | 0.0303   | +0.0019   | +6.50  |
| call_user_func_array   | 0.0381   | +0.0097   | +33.91 |
| InvokeCallUserFunc     | 0.0398   | +0.0113   | +39.60 |
+------------------------+----------+-----------+--------+

Overall Average
+------------------------+----------+-----------+--------+
| Invocation             | Time (s) | Delta (s) | %      |
+------------------------+----------+-----------+--------+
| directFunction         | 0.0089   | -0.0211   | -70.19 |
| directStatic           | 0.0098   | -0.0202   | -67.39 |
| directLambda           | 0.0109   | -0.0191   | -63.52 |
| directInstance         | 0.0116   | -0.0184   | -61.31 |
| directClosure          | 0.0150   | -0.0150   | -50.15 |
| Invoke                 | 0.0282   | -0.0018   | -6.13  |
| call_user_func         | 0.0300   |           |        |
| ClosureFactory         | 0.0316   | +0.0016   | +5.20  |
| assignedClosureFactory | 0.0328   | +0.0028   | +9.28  |
| call_user_func_array   | 0.0399   | +0.0099   | +33.02 |
| InvokeCallUserFunc     | 0.0418   | +0.0118   | +39.17 |
| directImplementation   | 0.0475   | +0.0175   | +58.28 |
+------------------------+----------+-----------+--------+

Time: 13.83 seconds, Memory: 1.00MB

PHP 7.1.2

$ php bench
Benchmarking call_user_func
Iterations: 100 000
Averaged over: 10
PHP 7.1.2 (cli) (built: Feb 14 2017 21:24:45) ( NTS MSVC14
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologi
Windows NT 10.0 build 14393 (Windows 10) AMD64

instance ~ [$instance, 'method']
+------------------------+----------+-----------+--------+
| Invocation             | Time (s) | Delta (s) | %      |
+------------------------+----------+-----------+--------+
| directInstance         | 0.0058   | -0.0080   | -58.11 |
| call_user_func         | 0.0138   |           |        |
| call_user_func_array   | 0.0148   | +0.0009   | +6.74  |
| directImplementation   | 0.0158   | +0.0019   | +13.93 |
| Invoke                 | 0.0188   | +0.0050   | +36.06 |
| ClosureFactory         | 0.0215   | +0.0076   | +55.29 |
| assignedClosureFactory | 0.0222   | +0.0084   | +60.48 |
| InvokeCallUserFunc     | 0.0254   | +0.0115   | +83.44 |
+------------------------+----------+-----------+--------+

static ~ 'Class::method'
+------------------------+----------+-----------+--------+
| Invocation             | Time (s) | Delta (s) | %      |
+------------------------+----------+-----------+--------+
| directStatic           | 0.0050   | -0.0236   | -82.55 |
| Invoke                 | 0.0273   | -0.0013   | -4.54  |
| ClosureFactory         | 0.0285   | -0.0001   | -0.43  |
| call_user_func         | 0.0286   |           |        |
| call_user_func_array   | 0.0295   | +0.0009   | +3.03  |
| assignedClosureFactory | 0.0296   | +0.0010   | +3.59  |
| InvokeCallUserFunc     | 0.0424   | +0.0138   | +48.27 |
| directImplementation   | 0.0534   | +0.0248   | +86.82 |
+------------------------+----------+-----------+--------+

function ~ 'function'
+------------------------+----------+-----------+---------+
| Invocation             | Time (s) | Delta (s) | %       |
+------------------------+----------+-----------+---------+
| directFunction         | 0.0043   | -0.0072   | -62.59  |
| call_user_func         | 0.0115   |           |         |
| call_user_func_array   | 0.0123   | +0.0007   | +6.42   |
| Invoke                 | 0.0188   | +0.0073   | +63.31  |
| ClosureFactory         | 0.0194   | +0.0078   | +68.02  |
| assignedClosureFactory | 0.0206   | +0.0091   | +79.05  |
| InvokeCallUserFunc     | 0.0235   | +0.0120   | +104.16 |
| directImplementation   | 0.0268   | +0.0153   | +132.95 |
+------------------------+----------+-----------+---------+

lambda ~ function($param) { return $param }
+------------------------+----------+-----------+---------+
| Invocation             | Time (s) | Delta (s) | %       |
+------------------------+----------+-----------+---------+
| directLambda           | 0.0063   | -0.0004   | -6.35   |
| call_user_func         | 0.0067   |           |         |
| call_user_func_array   | 0.0076   | +0.0008   | +12.17  |
| directImplementation   | 0.0091   | +0.0023   | +34.19  |
| Invoke                 | 0.0133   | +0.0066   | +97.79  |
| ClosureFactory         | 0.0156   | +0.0088   | +131.14 |
| assignedClosureFactory | 0.0172   | +0.0105   | +155.52 |
| InvokeCallUserFunc     | 0.0187   | +0.0120   | +177.78 |
+------------------------+----------+-----------+---------+

closure ~ function($param) use($use) { return $param }
+------------------------+----------+-----------+---------+
| Invocation             | Time (s) | Delta (s) | %       |
+------------------------+----------+-----------+---------+
| directClosure          | 0.0081   | -0.0005   | -6.31   |
| call_user_func         | 0.0086   |           |         |
| call_user_func_array   | 0.0093   | +0.0007   | +8.02   |
| directImplementation   | 0.0111   | +0.0024   | +28.31  |
| Invoke                 | 0.0151   | +0.0064   | +74.18  |
| ClosureFactory         | 0.0187   | +0.0101   | +116.39 |
| assignedClosureFactory | 0.0197   | +0.0110   | +127.78 |
| InvokeCallUserFunc     | 0.0222   | +0.0135   | +156.45 |
+------------------------+----------+-----------+---------+

Overall Average
+------------------------+----------+-----------+--------+
| Invocation             | Time (s) | Delta (s) | %      |
+------------------------+----------+-----------+--------+
| directFunction         | 0.0043   | -0.0096   | -68.92 |
| directStatic           | 0.0050   | -0.0089   | -64.04 |
| directInstance         | 0.0058   | -0.0081   | -58.22 |
| directLambda           | 0.0063   | -0.0075   | -54.44 |
| directClosure          | 0.0081   | -0.0058   | -41.57 |
| call_user_func         | 0.0139   |           |        |
| call_user_func_array   | 0.0147   | +0.0008   | +5.84  |
| Invoke                 | 0.0187   | +0.0048   | +34.61 |
| ClosureFactory         | 0.0207   | +0.0069   | +49.43 |
| assignedClosureFactory | 0.0219   | +0.0080   | +57.75 |
| directImplementation   | 0.0232   | +0.0094   | +67.53 |
| InvokeCallUserFunc     | 0.0264   | +0.0126   | +90.67 |
+------------------------+----------+-----------+--------+

Time: 7.69 seconds, Memory: 2.00MB

PHP 7.2.0

$ php bench
Benchmarking call_user_func
Iterations: 100 000
Averaged over: 10
PHP 7.2.0 (cli) (built: Nov 28 2017 23:48:32) ( NTS MSVC15 (Visual C++ 2017) x64 )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2017 Zend Technologies
Windows NT 10.0 build 17134 (Windows 10) AMD64

instance ~ [$instance, 'method']
+------------------------+----------+-----------+--------+
| Invocation             | Time (s) | Delta (s) | %      |
+------------------------+----------+-----------+--------+
| directInstance         | 0.0060   | -0.0070   | -53.88 |
| call_user_func         | 0.0131   |           |        |
| call_user_func_array   | 0.0136   | +0.0006   | +4.29  |
| directImplementation   | 0.0163   | +0.0032   | +24.67 |
| Invoke                 | 0.0193   | +0.0063   | +47.97 |
| ClosureFactory         | 0.0218   | +0.0087   | +66.62 |
| assignedClosureFactory | 0.0230   | +0.0100   | +76.26 |
| InvokeCallUserFunc     | 0.0248   | +0.0117   | +89.60 |
+------------------------+----------+-----------+--------+

static ~ 'Class::method'
+------------------------+----------+-----------+--------+
| Invocation             | Time (s) | Delta (s) | %      |
+------------------------+----------+-----------+--------+
| directStatic           | 0.0053   | -0.0234   | -81.62 |
| Invoke                 | 0.0241   | -0.0046   | -15.94 |
| call_user_func_array   | 0.0284   | -0.0004   | -1.29  |
| ClosureFactory         | 0.0286   | -0.0001   | -0.30  |
| call_user_func         | 0.0287   |           |        |
| assignedClosureFactory | 0.0298   | +0.0011   | +3.82  |
| InvokeCallUserFunc     | 0.0392   | +0.0105   | +36.61 |
| directImplementation   | 0.0527   | +0.0239   | +83.33 |
+------------------------+----------+-----------+--------+

function ~ 'function'
+------------------------+----------+-----------+---------+
| Invocation             | Time (s) | Delta (s) | %       |
+------------------------+----------+-----------+---------+
| directFunction         | 0.0046   | -0.0068   | -59.38  |
| call_user_func         | 0.0114   |           |         |
| call_user_func_array   | 0.0120   | +0.0006   | +4.87   |
| Invoke                 | 0.0194   | +0.0080   | +69.58  |
| ClosureFactory         | 0.0203   | +0.0089   | +77.65  |
| InvokeCallUserFunc     | 0.0231   | +0.0117   | +101.96 |
| assignedClosureFactory | 0.0236   | +0.0122   | +106.44 |
| directImplementation   | 0.0246   | +0.0132   | +115.53 |
+------------------------+----------+-----------+---------+

lambda ~ function($param) { return $param }
+------------------------+----------+-----------+---------+
| Invocation             | Time (s) | Delta (s) | %       |
+------------------------+----------+-----------+---------+
| call_user_func         | 0.0068   |           |         |
| directLambda           | 0.0071   | +0.0003   | +4.25   |
| call_user_func_array   | 0.0071   | +0.0003   | +4.90   |
| directImplementation   | 0.0094   | +0.0026   | +38.15  |
| ClosureFactory         | 0.0143   | +0.0075   | +110.75 |
| Invoke                 | 0.0145   | +0.0077   | +113.12 |
| assignedClosureFactory | 0.0154   | +0.0086   | +126.33 |
| InvokeCallUserFunc     | 0.0179   | +0.0111   | +163.06 |
+------------------------+----------+-----------+---------+

closure ~ function($param) use($use) { return $param }
+------------------------+----------+-----------+---------+
| Invocation             | Time (s) | Delta (s) | %       |
+------------------------+----------+-----------+---------+
| directClosure          | 0.0085   | -0.0004   | -4.16   |
| call_user_func         | 0.0089   |           |         |
| call_user_func_array   | 0.0089   | +0.0000   | +0.16   |
| directImplementation   | 0.0111   | +0.0022   | +24.76  |
| Invoke                 | 0.0154   | +0.0065   | +72.94  |
| ClosureFactory         | 0.0179   | +0.0090   | +100.94 |
| assignedClosureFactory | 0.0186   | +0.0097   | +109.08 |
| InvokeCallUserFunc     | 0.0203   | +0.0114   | +128.14 |
+------------------------+----------+-----------+---------+

Overall Average
+------------------------+----------+-----------+--------+
| Invocation             | Time (s) | Delta (s) | %      |
+------------------------+----------+-----------+--------+
| directFunction         | 0.0046   | -0.0091   | -66.30 |
| directStatic           | 0.0053   | -0.0085   | -61.71 |
| directInstance         | 0.0060   | -0.0078   | -56.29 |
| directLambda           | 0.0071   | -0.0067   | -48.52 |
| directClosure          | 0.0085   | -0.0053   | -38.15 |
| call_user_func         | 0.0138   |           |        |
| call_user_func_array   | 0.0140   | +0.0002   | +1.59  |
| Invoke                 | 0.0186   | +0.0048   | +34.58 |
| ClosureFactory         | 0.0206   | +0.0068   | +49.35 |
| assignedClosureFactory | 0.0221   | +0.0083   | +60.26 |
| directImplementation   | 0.0228   | +0.0090   | +65.53 |
| InvokeCallUserFunc     | 0.0251   | +0.0113   | +81.80 |
+------------------------+----------+-----------+--------+

Time: 7.97 seconds, Memory: 2.00MB
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].