網址 :
http://www.patternsforphp.org/doku.php?id=lazy_initialization
這不同於以往看到的 lazy loading 每次都要呼叫 __set 或 __get 來判斷是否有初始化的作法 , 這種做法只會呼叫一次 __set 或 __get , 我按照上述的作法寫了一段 code 來測試效能 , 在我的 I5 CPU 處理器上測得的效能差異有 5 倍之多
以下是範例程式
<?php error_reporting(E_ALL); class View { protected $_values = array(); } class Page { public $_view; public function __construct() { unset($this->_view); } public function __get($name) { if ($name === '_view') { $this->_view = new View(); return $this->_view; } } } class Page2 { private $___view; public function __construct() { } public function __get($name) { if ($name === '_view') { if(null === $this->___view) { $this->___view = new View(); } return $this->___view; } } } $page = new Page(); $page2 = new Page2(); $start = microtime(true); for($i=0; $i<10000; $i++) { $view = $page->_view; } printf("%f" , microtime(true)-$start); var_dump($view); $start = microtime(true); for($i=0; $i<10000; $i++) { $view = $page2->_view; } printf("%f" , microtime(true)-$start); var_dump($view);
類別 Page 是該網址介紹的方式 , Page2 是比較常見的方式 , 兩個方式都是 lazy loading 的作法 , 效能竟然差5倍 , 輸出結果如下
0.001325object(View)#3 (1) { ["_values":protected]=> array(0) { } } 0.006306object(View)#4 (1) { ["_values":protected]=> array(0) { } }
你有看記憶體的變化嗎
為什麼我把其中你說比較快的那個 public $view; 改成 private $view; 後反而變慢了?
而且變得比另一個還慢…
怎麼會這樣咧?
確實耶 ~ 也許 private 有多些檢查 , 看來這例子不適合每種狀況
不過很怪的,另一個比較慢的例子,我把private改成public
回傳竟然是 null
WHY ?
oh … 我讓你誤導了
第一次你問改成 private 這樣是錯的 … 因為 $page->_view 本來就要 public 才能存取 , 改成 private 不行 , 變成又會回到 __get() , 不相信你在 __get() 中隨便 echo 個東西 , 所以這個例子本來就該用 public
第二次你把 Page2 改成 public , 我的是 ok 的 , 除非你有改其它地方