2016-08-03 52 views
0

我想優化增加這個循環的速度。我想它,如果任何人有任何想法,以提高速度因爲有成千上萬的會員,它確實需要時間的時間來完成目前PHP的foreach代碼的性能速度

SQL存儲過程返回MembersMobileByVenue這 - > 例

FirstName Phone  Venue 
Aaron 04******* 7272CD46D51F 
Brad 04******* CF105BB0 
Adam 04******* 7272CD46D51F 
Craig 04******* CF105BB0 

PHP

$venueIDS = isset($_POST['location']) ? $_POST['location'] : array(); 

$msg = $_POST['message']; 
$response = array(); 

if(!empty($venueIDS)){ 
     $Members = GoldCardMembers::MembersMobileByVenue(); 
     foreach($Members as $Member){ 
      if(in_array($Member->Venue, $venueIDS)){ 
       $destination = $Member->Phone; 
       $text = 'Hi ' . $Member->FirstName . ' ' .$msg. '. Reply STOP to opt out'; 
       $ref = 'Members'; 

       $content = '&to='.rawurlencode($destination). 
          '&message='.rawurlencode($text). 
          '&ref='.rawurlencode($ref); 

       $smsbroadcast_response = sendSMS($content); 
       $response_lines = explode("\n", $smsbroadcast_response); 

       foreach($response_lines as $data_line){ 
        $message_data = ""; 
        $message_data = explode(':',$data_line); 
        if($message_data[0] == "OK"){ 
         array_push($response, "The message to ".$message_data[1]." was successful, with reference ".$message_data[2]."\n"); 
        }elseif($message_data[0] == "BAD"){ 
         array_push($response, "The message to ".$message_data[1]." was NOT successful. Reason: ".$message_data[2]."\n"); 
        }elseif($message_data[0] == "ERROR"){ 
         array_push($response, "There was an error with this request. Reason: ".$message_data[1]."\n"); 
        } 
       } 
      } 
     } 
} 

foreach($response as $message){ 
    echo $message; 
} 
+0

那裏有多個'foreach()'。包括可能導致問題的'if/elseif/etc'。馬上,您可以將您的'if/elseif/etc'改爲'switch/case'語句。這隻會提供邊際性能變化。你應該做的是調試和分析腳本以找到真正的瓶頸。它可能是幾件事中的任何一件,即:你的'GoldCardMembers :: MembersMobileByVenue()','sendSMS()','if/elseif',多個'foreach()'調用。我建議分塊處理數據並進行處理。 – Darren

回答

1
$venueIDS = isset($_POST['location']) ? $_POST['location'] : array(); 

$msg = $_POST['message']; 

$text = ""; 
$destination = ""; 
$content = ""; 
$response_lines = array(); 
$smsbroadcast_response = ""; 
$message_data = array(); 

if(!empty($venueIDS)){ 

     $Members = GoldCardMembers::MembersMobileByVenue(); 
     foreach($Members as $Member){ // O(n) size of $Members 
      if(in_array($Member->Venue, $venueIDS)){ // O(v) size of $venueIDs 

       $destination = rawurlencode($Member->Phone); 
       $text = rawurlencode($Member->FirstName . ' ' .$msg); 

       $content = '&to='. $destination . 
          '&message=Hi ' . $text . '. Reply STOP to opt out'. 
          '&ref=Members'; 

       $smsbroadcast_response = sendSMS($content); 
       $response_lines = explode("\n", $smsbroadcast_response); // O(r) number of "\n" occurances 

       foreach($response_lines as $data_line){ // O(r) 

        $message_data = explode(':',$data_line); // O(d) number of ":" occurances 

        if($message_data[0] == "OK"){ 
         echo "The message to ".$message_data[1]." was successful, with reference ".$message_data[2]."\n"; 
        }elseif($message_data[0] == "BAD"){ 
         echo "The message to ".$message_data[1]." was NOT successful. Reason: ".$message_data[2]."\n"; 
        }elseif($message_data[0] == "ERROR"){ 
         echo "There was an error with this request. Reason: ".$message_data[1]."\n"; 
        } 
       } 
      } 
     } 
} 

這裏是什麼,我做了一個清單:

  • 除去從底部for迴路和echo從主循環的$message直接代替
  • 除去$ref變種
  • 自聲明它們內部的初始化$destination$text$content$response_lines$smsbroadcast_response$message_data VARS的for循環外循環與每次迭代是次優

這就是我現在能想到的。

注意事項作進一步的改進:

我想探討的sendSMS性能您使用。它可能是減慢速度的組件之一。

爲了深入挖掘,分析性能的有用工具是big Oh notation。所以我已經給標籤循環組件添加了評論。

因爲我們在看多個嵌套循環,所以我們在這裏通常有類似O(N^3)的東西。

然而,我們可以寫方程更詳細的像這樣:

爲O(n *(V + 2R)* d)

(請查看代碼的註釋,以瞭解每個變量代表)

由於您要求高「n」(成員數量),我會研究如何使「v」,「r」或「d」等其他變量更小的方法。

消除這些變量完全如消除

$message_data = explode(':',$data_line);

對性能最高的正面影響(假設仍實現相同的功能)。