What's better at freeing memory with PHP: unset() or $var = null

前端 未结 13 1983
陌清茗
陌清茗 2020-11-22 08:57

I realise the second one avoids the overhead of a function call (update, is actually a language construct), but it would be interesting to know if one is be

相关标签:
13条回答
  • 2020-11-22 09:39

    I created a new performance test for unset and =null, because as mentioned in the comments the here written has an error (the recreating of the elements). I used arrays, as you see it didn't matter now.

    <?php
    $arr1 = array();
    $arr2 = array();
    for ($i = 0; $i < 10000000; $i++) {
        $arr1[$i] = 'a';
        $arr2[$i] = 'a';
    }
    
    $start = microtime(true);
    for ($i = 0; $i < 10000000; $i++) {
        $arr1[$i] = null;
    }
    $elapsed = microtime(true) - $start;
    
    echo 'took '. $elapsed .'seconds<br>';
    
    $start = microtime(true);
    for ($i = 0; $i < 10000000; $i++) {
        unset($arr2[$i]);
    }
    $elapsed = microtime(true) - $start;
    
    echo 'took '. $elapsed .'seconds<br>';
    

    But i can only test it on an PHP 5.5.9 server, here the results: - took 4.4571571350098 seconds - took 4.4425978660583 seconds

    I prefer unset for readability reasons.

    0 讨论(0)
  • 2020-11-22 09:41

    By doing an unset() on a variable, you've essentially marked the variable for 'garbage collection' (PHP doesn't really have one, but for example's sake) so the memory isn't immediately available. The variable no longer houses the data, but the stack remains at the larger size. Doing the null method drops the data and shrinks the stack memory almost immediately.

    This has been from personal experience and others as well. See the comments of the unset() function here.

    I personally use unset() between iterations in a loop so that I don't have to have the delay of the stack being yo-yo'd in size. The data is gone, but the footprint remains. On the next iteration, the memory is already being taken by php and thus, quicker to initialize the next variable.

    0 讨论(0)
  • 2020-11-22 09:46

    It works in a different way for variables copied by reference:

    $a = 5;
    $b = &$a;
    unset($b); // just say $b should not point to any variable
    print $a; // 5
    
    $a = 5;
    $b = &$a;
    $b = null; // rewrites value of $b (and $a)
    print $a; // nothing, because $a = null
    
    0 讨论(0)
  • 2020-11-22 09:47

    unset code if not freeing immediate memory is still very helpful and would be a good practice to do this each time we pass on code steps before we exit a method. take note its not about freeing immediate memory. immediate memory is for CPU, what about secondary memory which is RAM.

    and this also tackles about preventing memory leaks.

    please see this link http://www.hackingwithphp.com/18/1/11/be-wary-of-garbage-collection-part-2

    i have been using unset for a long time now.

    better practice like this in code to instanly unset all variable that have been used already as array.

    $data['tesst']='';
    $data['test2']='asdadsa';
    ....
    nth.
    

    and just unset($data); to free all variable usage.

    please see related topic to unset

    How important is it to unset variables in PHP?

    [bug]

    0 讨论(0)
  • 2020-11-22 09:53

    Code example from comment

    echo "PHP Version: " . phpversion() . PHP_EOL . PHP_EOL;
    
    $start = microtime(true);
    for ($i = 0; $i < 10000000; $i++) {
        $a = 'a';
        $a = NULL;
    }
    $elapsed = microtime(true) - $start;
    
    echo "took $elapsed seconds" . PHP_EOL;
    
    
    
    $start = microtime(true);
    for ($i = 0; $i < 10000000; $i++) {
        $a = 'a';
        unset($a);
    }
    $elapsed = microtime(true) - $start;
    
    echo "took $elapsed seconds" . PHP_EOL;
    

    Running in docker container from image php:7.4-fpm and others..

    PHP Version: 7.4.8
    took 0.22569918632507 seconds null
    took 0.11705803871155 seconds unset
    took 0.20791196823121 seconds null
    took 0.11697316169739 seconds unset
    
    PHP Version: 7.3.20
    took 0.22086310386658 seconds null
    took 0.11882591247559 seconds unset
    took 0.21383500099182 seconds null
    took 0.11916995048523 seconds unset
    
    PHP Version: 7.2.32
    took 0.24728178977966 seconds null
    took 0.12719893455505 seconds unset
    took 0.23839902877808 seconds null
    took 0.12744522094727 seconds unset
    
    PHP Version: 7.1.33
    took 0.51380109786987 seconds null
    took 0.50135898590088 seconds unset
    took 0.50358104705811 seconds null
    took 0.50115609169006 seconds unset
    
    PHP Version: 7.0.33
    took 0.50918698310852 seconds null
    took 0.50490307807922 seconds unset
    took 0.50227618217468 seconds null
    took 0.50514912605286 seconds unset
    
    PHP Version: 5.6.40
    took 1.0063569545746 seconds null
    took 1.6303179264069 seconds unset
    took 1.0689589977264 seconds null
    took 1.6382601261139 seconds unset
    
    PHP Version: 5.4.45
    took 1.0791940689087 seconds null
    took 1.6308979988098 seconds unset
    took 1.0029168128967 seconds null
    took 1.6320278644562 seconds unset
    
    

    But, with other example:

    <?php
    ini_set("memory_limit", "512M");
    
    echo "PHP Version: " . phpversion() . PHP_EOL . PHP_EOL;
    
    $start = microtime(true);
    $arr = [];
    for ($i = 0; $i < 1000000; $i++) {
        $arr[] = 'a';
    }
    $arr = null;
    $elapsed = microtime(true) - $start;
    
    echo "took $elapsed seconds" . PHP_EOL;
    
    
    
    $start = microtime(true);
    $arr = [];
    for ($i = 0; $i < 1000000; $i++) {
        $arr[] = 'a';
    }
    unset($arr);
    $elapsed = microtime(true) - $start;
    
    echo "took $elapsed seconds" . PHP_EOL;
    

    Results:

    PHP Version: 7.4.8
    took 0.053696155548096 seconds
    took 0.053897857666016 seconds
    
    PHP Version: 7.3.20
    took 0.054572820663452 seconds
    took 0.054342031478882 seconds
    
    PHP Version: 7.2.32
    took 0.05678391456604 seconds
    took 0.057311058044434 seconds
    
    
    PHP Version: 7.1.33
    took 0.097366094589233 seconds
    took 0.073100090026855 seconds
    
    PHP Version: 7.0.33
    took 0.076443910598755 seconds
    took 0.077098846435547 seconds
    
    PHP Version: 7.0.33
    took 0.075634002685547 seconds
    took 0.075317859649658 seconds
    
    PHP Version: 5.6.40
    took 0.29681086540222 seconds
    took 0.28199100494385 seconds
    
    PHP Version: 5.4.45
    took 0.30513095855713 seconds
    took 0.29265689849854 seconds
    
    
    0 讨论(0)
  • 2020-11-22 09:54

    PHP 7 is already worked on such memory management issues and its reduced up-to minimal usage.

    <?php
      $start = microtime(true);
      for ($i = 0; $i < 10000000; $i++) {
        $a = 'a';
        $a = NULL;
      }
      $elapsed = microtime(true) - $start;
    
      echo "took $elapsed seconds\r\n";
    
      $start = microtime(true);
      for ($i = 0; $i < 10000000; $i++) {
         $a = 'a';
         unset($a);
      }
      $elapsed = microtime(true) - $start;
    
      echo "took $elapsed seconds\r\n";
    
    ?>
    

    PHP 7.1 Outpu:

    took 0.16778993606567 seconds took 0.16630101203918 seconds

    0 讨论(0)
提交回复
热议问题