1

I realized, that closures are consuming more memory. Could someone help me to understand why it is happening like that, please? Also, having following results, is it not recommended to use closures?

$value = 10;
$memory = memory_get_usage();

$fun = static function ($add, $value) {
    $value += $add;

    echo $value;
};

$fun(10, $value);

echo ' | ' . $value . ' | memory: ' . (memory_get_usage() - $memory);

Output:

20 | 10 | memory: 368

$value = 10;
$memory = memory_get_usage();

$closure = static function (int $add) use ($value) {
    $value += $add;

    echo $value;
};

$closure(10);

echo ' | ' . $value . ' | memory: ' . (memory_get_usage() - $memory);

Output:

20 | 10 | memory: 752

(the same is happening for objects)

Jazi
  • 6,569
  • 13
  • 60
  • 92
  • You'd better ask the PHP developers... maybe has to do with the way how the second parameter is injected. Btw: both examples are closures... – Honk der Hase Nov 29 '20 at 11:39
  • @LarsStegelitz Isn't that the 1st one is an anonymous function and 2nd is a closure? If not, then I don't fully understand what is a closure then :/. – Jazi Nov 29 '20 at 12:03
  • 1
    a closure IS an anonymous function... it's just another term. https://www.php.net/manual/en/functions.anonymous.php – Honk der Hase Nov 29 '20 at 12:08
  • @LarsStegelitz Hmm... so I'm confused. Was reading other articles as this which was describing that those are different things: https://stackoverflow.com/questions/220658/what-is-the-difference-between-a-closure-and-a-lambda, and an example quote: "Not all closures are lambdas and not all lambdas are closures." – Jazi Nov 29 '20 at 12:16
  • @UrmatZhenaliev Isn't that functions assigned to a variable are lambdas (anonymous functions)? They do not have a name as they're just assigned to a variable. I'm confused even more, so I'm asking :). – Jazi Nov 29 '20 at 12:45
  • 1
    The terms "closure" and "anonymous function" are often used for the same thing. Strictly speaking they are not the same. A closure is the combination of a function and its environment. In this case the "use" keyword defines a variable in that environment, which is not visible outside of it. OTOH, you could argue that the first example is a closure as well, just with an empty environment. see https://en.wikipedia.org/wiki/Closure_(computer_programming) – EricSchaefer Nov 29 '20 at 14:42

1 Answers1

1

From https://stackoverflow.com/a/10304027/7265862:

  1. use is early binding. That means the variable values are COPIED upon DEFINING the closure. So modifying $tax inside the closure has no external effect, unless it is a pointer, like an object is.

It means, that in your second example you actually copied $value. While in first example you pass the pointer to $add and $value. Therefore, your script consumed more memory in second function

is it not recommended to use closures?

I guess it's opinion and task based question. Most of developers prefer clean code rather few bytes. But some projects work under a very high load, thus managers demand to save every byte.

In my projects, I try to maintain the most concise, readable and maintainable code. So, I would prefer lambdas, rather closures. Not because of optimization, but to make my function independent from out of scope variables.

And to optimize the project using other means: cache, database, architecture. Because trying to save those measly few bytes, you can frustrate the whole project.

Urmat Zhenaliev
  • 1,497
  • 8
  • 22
  • This cannot explain why the memory usage is doubled, a pointer copy doesn't need about 400 bytes. – shingo Nov 29 '20 at 15:02