2012-02-18 26 views
3

我忽略了一些代碼,這些代碼是爲了在產品頁面上生成A-Z導航而編寫的,而且它的做法是for循環;使用ascii octals 65-91和PHP的chr()函數。我想知道是否有更簡單和/或更有效的方式來做這件事,我發現PHP的range()函數支持字母範圍。PHP的範圍('A','Z')是否返回一個靜態數組?

後,我寫我的測試代碼比較不同的方法,有幾個問題浮現在腦海:

  1. 不PHP店字母表中的靜態數組?
  2. 如何更深入地查看PHP層以下的內容以查看 發生了什麼?

我有一個PHP腳本的cachegrind,除了環境配置之外,還可以根據需要連接它。對於那些誰可能想知道在它被執行的機器規格,這裏有一些鏈接:

根@針線:〜$ lshw http://pastebin.com/cZZRjJcR

根@針線:〜$ SYSINFO http://pastebin.com/ihQkkPAJ

<?php 
/* 
* determine which method out of 3 for returning 
* an array of uppercase alphabetic characters 
* has the highest performance 
* 
* +++++++++++++++++++++++++++++++++++++++++++++ 
* 
* 1) Array $alpha = for($x = 65; $x < 91; $x++) { $upperChr[] = chr($x); } 
* 2) Array $alpha = range(chr(65), chr(90); 
* 3) Array $alpha = range('A', 'Z'); 
* 
* +++++++++++++++++++++++++++++++++++++++++++++ 
* 
* test runs with iterations: 
* 
* 10,000: 
* - 1) upperChrElapsed: 0.453785s 
* - 2) upperRangeChrElapsed: 0.069262s 
* - 3) upperRangeAZElapsed: 0.046110s 
* 
* 100,000: 
* - 1) upperChrElapsed: 0.729015s 
* - 2) upperRangeChrElapsed: 0.078652s 
* - 3) upperRangeAZElapsed: 0.052071s 
* 
* 1,000,000: 
* - 1) upperChrElapsed: 50.942950s 
* - 2) upperRangeChrElapsed: 10.091785s 
* - 3) upperRangeAZElapsed: 8.073058s 
*/ 

ini_set('max_execution_time', 0); 
ini_set('memory_limit', 0); 

define('ITERATIONS', 1000000); // 1m loops x3 

$upperChrStart = microtime(true); 
for($i = 0; $i <= ITERATIONS; $i++) { 
    $upperChr = array(); 
    for($x = 65; $x < 91; $x++) { 
      $upperChr[] = chr($x); 
    } 
} 
$upperChrElapsed = microtime(true) - $upperChrStart; 

// +++++++++++++++++++++++++++++++++++++++++++++ 

$upperRangeChrStart = microtime(true); 
for($i = 0; $i <= ITERATIONS; $i++) { 
    $upperRangeChr = range(chr(65), chr(90)); 
} 
$upperRangeChrElapsed = microtime(true) - $upperRangeChrStart; 

// +++++++++++++++++++++++++++++++++++++++++++++ 

$upperRangeAZStart = microtime(true); 
for($i = 0; $i <= ITERATIONS; $i++) { 
    $upperRangeAZ = range('A', 'Z');  
} 
$upperRangeAZElapsed = microtime(true) - $upperRangeAZStart; 

printf("upperChrElapsed: %f\n", $upperChrElapsed); 
printf("upperRangeChrElapsed: %f\n", $upperRangeChrElapsed); 
printf("upperRangeAZElapsed: %f\n", $upperRangeAZElapsed); 

?> 
+0

我不知道你,但我從來沒有多餘的2微秒擔心我最少。這是我對PHP的主要問題:不是語言本身,而是那些堅持做無用的垃圾基準測試的大米。無論如何,一百萬次迭代的東西不應該在循環中需要額外的2秒!哦,gn0! pfft – cHao 2012-02-18 01:33:04

+1

@cHao爲自己說話。在我們的應用程序的主循環中額外增加了2微秒,我們還需要額外花費3000美元購買每個數據中心所需的硬件。如果它在內部循環中爲2微秒,則花費更多。 – Crashworks 2012-02-18 01:52:04

+0

@Crashworks:如果這個小小的速度差異花了那麼多錢,坦白地說,你不應該使用PHP。你可以使用C++(甚至是(C#)),它會節省數百萬美元。當然,這裏真正的優化(將創建同一陣列 - 我們剛剛使用的東西移出循環)是免費的。要點是,最快兩者之間的速度差異可以忽略不計,通過改進算法可以更好地解決速度問題,而不是通過更快地創建陣列來解決。 – cHao 2012-02-18 06:37:11

回答

2

PHP浪費內存是否保留一組字母?我會懷疑它。 range()也可以處理各種值。

如果在這種情況下性能出現問題,您可能需要在循環之外聲明該數組,以便可以重新使用該數組。然而,微型優化很少會帶來巨大收益。使用大型應用程序進行分析以獲得顯着收益。

至於較低級別的分析,您可以簡單地在PHP CLI上使用valgrind。我也看到它在apache進程中使用。

相關:How to profile my C++ application on linux