網址 :
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 的 , 除非你有改其它地方