The strange PHP reference efficiency problem analysis
- 2020-05-16 06:27:49
- OfStack
The function is as follows:
Do you see anything wrong with this function? In fact, there is a big problem in the function:
$timequeue = &$arr['timequeue'];
It took nearly 40 seconds for the program to read in 22M data and generate a linked list of time nodes. The time to delete the line and use $arr['timequeue'] was shortened by 30 seconds, and it only took about 10 seconds to process 22M.
Do you see what the problem is? The problem is the count function. The actual content space to which PHP points variables is marked for reference types and non-reference types, as shown in the following code:
Only one copy of 'ofstack.com' will be copied when $b and $c are modified. In this case, the content space type of 'ofstack.com' is non-reference type. If you change it to the following code:
What's going to happen to this? Is it still 1 memory space for 'ofstack.com'? No, because $c is a reference to $a, and the storage space to which $a points needs to be marked as a reference type, then a separate copy of 'ofstack.com' must be made for $b, since $b points to a non-reference type.
We can understand that $c is now a reference to $a. If $b is still executing $a's space, then modifying $c will cause $b to change as well, so at this point, a copy of the reference must be made even if there is no write. It can also be understood that php points to only two types of memory space for variables: non-reference and reference. The two types cannot be mixed and transferred. If you need to change the state of the memory space somewhere, you need copy1.
Here's why an extra $timequeue = &$arr['timequeue'] causes count to slow down. Remember when the c function was called? In fact, the parameters we passed in need of a copy of copy1 and php as well, but copy on writing mechanism makes count not really copy when passing in a non-reference type, but $timequeue = &$arr['timequeue'] specifies the memory space of $timequeue as a reference type, while count ['timequeue'] requires a non-reference type, so count needs an copy1 copy of $arr['timequeue']. Directly pass $arr['timequeue'] why is there no problem? count of course USES the copy on writing mechanism, array_shift and array_push? They are incoming references, so don't worry about this not changing the $arr['timequeue'] type but actually passing in the 1 alias of $arr['timequeue'].
I have just started learning PHP, and the above analysis is not necessarily correct or comprehensive. You can email me on my home page.
function update_timelist(&$arr,$timestamp,$threshold){
$timequeue = &$arr['timequeue'];
while(!empty($timequeue[0])&&($timestamp-$timequeue[0])>$threshold){
array_shift($timequeue);
}
array_push($timequeue, $timestamp);
if($arr['count']<count($timequeue)){
$arr['count'] = count($timequeue);
}
}
Do you see anything wrong with this function? In fact, there is a big problem in the function:
$timequeue = &$arr['timequeue'];
It took nearly 40 seconds for the program to read in 22M data and generate a linked list of time nodes. The time to delete the line and use $arr['timequeue'] was shortened by 30 seconds, and it only took about 10 seconds to process 22M.
function update_timelist(&$arr,$timestamp,$threshold){
while(!empty($arr['timequeue'][0])&&($timestamp-$arr['timequeue'][0])>$threshold){
array_shift($arr['timequeue']);
}
array_push($arr['timequeue'], $timestamp);
if($arr['count']<count($arr['timequeue'])){
$arr['count'] = count($arr['timequeue']);
}
Do you see what the problem is? The problem is the count function. The actual content space to which PHP points variables is marked for reference types and non-reference types, as shown in the following code:
$a = 'ofstack.com';
$b = $a;
$c = $b;
Only one copy of 'ofstack.com' will be copied when $b and $c are modified. In this case, the content space type of 'ofstack.com' is non-reference type. If you change it to the following code:
$a = 'ofstack.com';
$b = $a;
$c = &$a;
What's going to happen to this? Is it still 1 memory space for 'ofstack.com'? No, because $c is a reference to $a, and the storage space to which $a points needs to be marked as a reference type, then a separate copy of 'ofstack.com' must be made for $b, since $b points to a non-reference type.
We can understand that $c is now a reference to $a. If $b is still executing $a's space, then modifying $c will cause $b to change as well, so at this point, a copy of the reference must be made even if there is no write. It can also be understood that php points to only two types of memory space for variables: non-reference and reference. The two types cannot be mixed and transferred. If you need to change the state of the memory space somewhere, you need copy1.
Here's why an extra $timequeue = &$arr['timequeue'] causes count to slow down. Remember when the c function was called? In fact, the parameters we passed in need of a copy of copy1 and php as well, but copy on writing mechanism makes count not really copy when passing in a non-reference type, but $timequeue = &$arr['timequeue'] specifies the memory space of $timequeue as a reference type, while count ['timequeue'] requires a non-reference type, so count needs an copy1 copy of $arr['timequeue']. Directly pass $arr['timequeue'] why is there no problem? count of course USES the copy on writing mechanism, array_shift and array_push? They are incoming references, so don't worry about this not changing the $arr['timequeue'] type but actually passing in the 1 alias of $arr['timequeue'].
I have just started learning PHP, and the above analysis is not necessarily correct or comprehensive. You can email me on my home page.