📜 ⬆️ ⬇️

Negative side of referring values

Without any lyrics, right: the use of links to transfer values ​​reduces performance . We think that instead of transmitting a copy of a variable, the script passes the variable itself, based on which we conclude that this should work faster. Alas, this is a delusion. To understand why, let's deal with how the Zend Engine processor handles values.

When working with variables, the Zend Engine processor implements a value system with reference counting, copying while writing. This means that many variables can point to the same value . At the same time a large number of memory blocks are not consumed. Consider an example:

  1. <?php $a = array(1, 2, 3, 4, 5); $b = $a; ?>
  2. <?php $a = array(1, 2, 3, 4, 5); $b = $a; ?>
  3. <?php $a = array(1, 2, 3, 4, 5); $b = $a; ?>
  4. <?php $a = array(1, 2, 3, 4, 5); $b = $a; ?>

The variable $ b is assigned the value of the variable $ a , while the data itself is not copied anywhere! Instead, the $ b variable is converted in such a way that it points to the same place in memory where the $ a variable is stored, i.e. to the storage location of the initially assigned data (in our case it is an array with values). The processor marks the array and increases the reference count to 2. Consider another example:
')
  1. <? php
  2. $ a = array (1, 2, 3, 4, 5);
  3. $ b = $ a;
  4. $ a [] = 6;
  5. print_r ($ a);
  6. print_r ($ b);
  7. ?>

I hope no one expected the value of the variables to be the same? :) Joke. So what happened if we were talking about references to one place in memory? When we started modifying the array, the Zend Engine processor separates versions $ a and $ b . As soon as the processor detects a write operation by a value that has more than one reference, data is copied — an identical value is created that is located in another area of ​​memory that is not related to any other reference. And only after the copying stage during the recording is completed the operation will be continued. Such timely duplication improves performance without any side effects. And all thanks to the exclusion of copying unnecessary data!

However, all of the above does not answer the question “why is the transfer by reference a bad thing?”.

First, it is useless, because thanks to the link counting mechanism, there is no need to pass variables by reference. The processor itself will avoid unnecessary copying at the slightest opportunity.

Secondly, the processor ... so let's take a look at an example. Add a content listing function to our code:

  1. <? php
  2. function prepareArr (& $ arr) {
  3. print count ($ arr) * 2;
  4. }
  5. $ a = array (1, 2, 3, 4, 5);
  6. $ b = $ a;
  7. prepareArr ($ a);
  8. ?>

When the processor starts sending the $ a array in the prepareArr () function, it determines that the value (our array) needs to be passed by reference. It further finds that the reference count is greater than 1 (in our case, it is equal to 2). Since the value of the $ a array is passed by reference and any changes our function can make to it should not affect $ b , the processor makes separate copies for the $ a and $ b arrays. When passing the value of a variable to a function, Zeng Engine can simply increment the reference count.

Nanooptimization, you think? Maybe, but when passing values ​​by reference, you lose 30% of the performance of this operation. And the more data you work with, the more the speed of the operation decreases.

For example, the execution of the last example in a cycle of 50,000 iterations will be 0.4538291 seconds. The same script, but without the use of links, takes 0.3090010 seconds, i.e. 30% faster. If we increase the data volume to 6.5 kb, then the execution of cycles with 5000 iterations will be 19.7765129 seconds. and 7.3865049 sec. respectively. The last figure, as you already guessed, is the result of executing the function without using references.

In the performance key, it is not recommended to use the transfer of values ​​by reference. The use of links is justified only when it makes sense from a functional point of view.

Source: https://habr.com/ru/post/43489/


All Articles