0

As I've read throughout other posts, passing-by-reference to a function offers much worse performance than passing-by-value(which utilizes copy-on-write). Does this also apply when passing a variable through the 'use' operator in a closure?

For example:

$message = 'hello';

$greetings = function () use (&$message) {
    echo $message;
};

$huge_number = 100000000;

while ($huge_number > 0) {
    $greetings();
    $huge_number--;
}

Will this also incur the overhead associated with passing variables by-reference? If so, does that mean that internally PHP 're-captures' the local scope everytime the function is called?

CodeIntern
  • 1,370
  • 2
  • 11
  • 15
  • 1
    Test it and find out. Time both versions of the code using `microtime(true)` You may have to run them in a loop so it takes more then a split second. Further if you are not modifying the data, your comparing an apple to an orange, because instead of by-reference you would have to return the data and set it. (Which is the reason for it) – ArtisticPhoenix Oct 15 '18 at 16:43
  • 1
    When running *any* benchark on this, take in ind that you're measuring the loop foremost. The reference will only be bound once to the anonymous function, btw. It's not a real closure, and PHP does not capture anything from the current scope (other than `use` declarations). – mario Oct 15 '18 at 19:16

1 Answers1

2

This really isn't an answer but an explanation:

passing-by-reference to a function offers much worse performance than passing-by-value

This may be but it's not really the purpose of pass by reference. The purpose is to update the original without returning data or making a copy of the data.

So to test this

$greetings = function () use (&$message) {
   echo $message;
};

VS

$greetings = function () use ($message) {
     echo $message;
};

Is not really fair as the first one is doing things the second one is not. And there is no purpose (or point) to use Pass by Reference there.

A fair test would be this:

$message = "foo";

$greetings = function () use (&$message) {
   $message .= " bar";
};

$greetings();
//$message = "foo bar";

VS

$message = "foo";

$greetings = function() use ($message){
    return $message . " bar";
};

$message = $greetings();
//$message = "foo bar";

So to test just calling it without testing how it affects the data, doesn't do it justice. In other words, the first pair of examples maybe Pass-by reference is slower. But in the second pair is that still true, how about memory usage etc.

In any case you can time them like this:

$start = microtime(true);
//...some code to test
echo format_number((microtime(true) - $start), 2));

But you may have to do it in a loop to make it take enough time to measure. And even then, it will depend in large part on what the data is you are passing.

ArtisticPhoenix
  • 21,464
  • 2
  • 24
  • 38