用while next訪問陣列,比foreach快上近7倍?
偶然從php官網的文件,看到一篇討論while和foreach陣列訪問速度的文章,才知道有next這個關鍵字,而且搭配while來操作,速度會比foreach快上不少…真是如此嗎?花了點時間研究一下。
******************************************************
30870 Element Array Traversing
[test_time] [BEGINS/RESETS @ time_start = 1060977996.689]
0.2373 seg later -> while (list ($key, $val) = each ($array)) ENDS
[test_time] [BEGINS/RESETS @ time_start = 1060977996.9414]
0.1916 seg later -> while (list ($key,) = each ($array)) ENDS
[test_time] [BEGINS/RESETS @ time_start = 1060977997.1513]
0.1714 seg later -> foreach ($array AS $key=>$value) ENDS
[test_time] [BEGINS/RESETS @ time_start = 1060977997.3378]
0.0255 seg later -> while ($next = next($array)) ENDS
[test_time] [BEGINS/RESETS @ time_start = 1060977997.3771]
0.1735 seg later -> foreach ($array AS $value) ENDS
**************************************************************
foreach is fatser than a while (list – each), true.
However, a while(next) was faster than foreach.
30870 Element Array Traversing
[test_time] [BEGINS/RESETS @ time_start = 1060977996.689]
0.2373 seg later -> while (list ($key, $val) = each ($array)) ENDS
[test_time] [BEGINS/RESETS @ time_start = 1060977996.9414]
0.1916 seg later -> while (list ($key,) = each ($array)) ENDS
[test_time] [BEGINS/RESETS @ time_start = 1060977997.1513]
0.1714 seg later -> foreach ($array AS $key=>$value) ENDS
[test_time] [BEGINS/RESETS @ time_start = 1060977997.3378]
0.0255 seg later -> while ($next = next($array)) ENDS
[test_time] [BEGINS/RESETS @ time_start = 1060977997.3771]
0.1735 seg later -> foreach ($array AS $value) ENDS
**************************************************************
foreach is fatser than a while (list – each), true.
However, a while(next) was faster than foreach.
為什麼用while next會比foreach快?那是因為foreach操作陣列時得先複製一個新的陣列變數參考,而next則是在暨有變數裡移動指標。
註1:
foreach官方文件有寫,只有在進行陣列變數參考reference操作時,才需複製一個新的陣列,該文的測試程式剛好是在用參考。
所以嚴格來講,不是while next快,而是foreach在那種狀況操作下是慢的…
註2:
另外,就該文給的測速範例來看,其實while next少算了一個(後面的討論串有提到)…
使用例:
$tests = array( array("test1" => "123" , "test2" => "456" , "test3" => "789"), array("test1" => "111" , "test2" => "222" , "test3" => "333"), array("test1" => "444" , "test2" => "555" , "test3" => "666"), array("test1" => "777" , "test2" => "888" , "test3" => "999") ); foreach ($tests as $test) { echo $test['test1'].'-'.$test['test2'].'-'.$test['test3'].' '; next($tests); } reset($tests); while ($test = current($tests)) { echo $test['test1'].'-'.$test['test2'].'-'.$test['test3'].' '; next($tests); }
原文參考:while
追求Coging的效能…是程式設計師的功課。XD