2016-08-03 28 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);

对性能最高的正面影响(假设仍实现相同的功能)。