PHP小研究拿出來和大家分享

來源:互聯網
上載者:User

  小小見解(參考風雪之隅及網上相關資料):

  引用和複製的區別:

  大家都知道引用其實就是:$a = 1;$b = $a;改變$a或者$b不會影響對方。而引用是按地址傳值:$a = 1;$b = &$a;改變任何一個另一個值都會改變。

  但是在末尾加個why呢,為什麼會是這樣呢?

  大家需要理解php裡面的兩個機制就是copy on write 和 change on write:

  copy on write :寫時複製;應用於變數複製。例如上面例子,$a = 1;$a變數存放在符號表裡面,而值"1"存放在zval中。意思也就是說php裡面存放

  的變數,每個變數名都存放在符號表裡面,每個符號對應一個zval;zval可以看做一個容器,裡面存放著變數值,變數類型,等等。

  $a = 1;$b = $a;可能會有人認為記憶體裡有兩個"1",實際上並不是這樣的,$a與$b都指向存放1的zval容器。可以形象比喻為,$a與$b各自有條線指向

  zval,zval中有個參數是refcount來計數的,就是統計有多少線指向自己的。當有個變數進行複製時候refcount就會加1。即:$a = 1;$b = $a;此時存

  放1的zval結構裡面的refcount值為2。php裡面有個函數可以查看,就是debug_zval_dump($v);當debug_zval_dump($a);時候計數為3,因為$a是以

  傳值得形式傳給debug_zval_dump的所以列印出來的值是3。

  接著說明一個問題,就是unset,它的作用是使變數的refcount數減一。也就是當refcount值為0的時候才會將變數值占的記憶體釋放掉。當unset($b)的時候

  1並沒有在記憶體中釋放掉,而是指向它的引用數減。

  當中說到的記憶體釋可能並不會釋放給系統(OS),php會為自己開闢個指定大小的記憶體,當有變數產生時候會去自己的記憶體區裡面申請,當釋放的時候會釋放到自

  己的記憶體地區裡面。對於提高效率有很大協助了。但是當超出這個指定值得時候會去向系統申請記憶體了,那時候再釋放的時候就會釋放給系統了

  關於引用,zval裡面有另一個參數is_ref來標記(標記是否為真正的引用),此值預設為0,例如:$a = 1;$b = &$a;此時debug_zval_dump($a);結果為1,

  refcount = 2,is_ref = 3,

  版本5.2.17源碼中的zval聯合體,可以去官網下載

  typedef union _zvalue_value {

  long lval; /* long value */

  double dval; /* double value */

  struct {

  char *val;

  int len;

  } str;

  HashTable *ht; /* hash table value */

  zend_object_value obj;

  } zvalue_value;

  struct _zval_struct {

  /* Variable information */

  zvalue_value value; /* value */

  zend_uint refcount;

  zend_uchar type; /* active type */

  zend_uchar is_ref;

  };

  測試幾個程式的執行速度

  測試環境:

  OS:win7

  php vesion 5.2.9

  apache2.0

  1.判斷變數值是否為空白用'!'加變數名字與empty加變數名做執行時間對比(迴圈1千萬次)

  if裡面使用!$a執行時間為:2.40036678314s

  if裡面使用empty($a)執行時間為:2.52875089645s

  測試代碼:  

  $start = microtime(true);

  $a = '';

  for($i=0; $i < 10000000; $i++){

  if(!$a){//可改為empty($a)

  echo " ";

  }

  }

  $end = microtime(true);

  echo "執行時間為:",($end-$start),"s";

  ?> 

 

  2.使用if-esle與使用三元運算子做執行時間對比(迴圈1千萬次)

  使用if-else 執行時間為:2.37516283989s

  使用三元運算子 執行時間為:2.14390015602s

  三元運算子運行時候,每次變數都會複製一次

  if-else不會,影響甚微,只是拿出來和大家分享下

  測試代碼:  

  $start = microtime(true);

  $a = range(1, 1000);

  for($i=0; $i < 10000000; $i++){

  if(isset($a)){

  echo " ";

  }else{

  echo "";

  }

  }

  $end = microtime(true);

  echo "執行時間為:",($end-$start),"s";

  ?>

  

  $start = microtime(true);

  $a = range(1, 1000);

  for($i=0; $i < 10000000; $i++){

  isset($a) ? " " : "";

  }

  $end = microtime(true);

  echo "執行時間為:",($end-$start),"s";

  ?> 

 



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.