dqst96444 2014-01-17 19:07
浏览 79
已采纳

对于大型逗号分隔的子串,foreach或in_array更快检查?

I read this post: faster than in_array? but I tried an experiment with a part of my php code. In my site's database users have stored a string ($UserString here) of comma-separated text substrings. I originally was checking if a user input ($PostedVar) was a member of the array created by exploding $UserString by using a foreach loop (I have recreated a small part of the relevant code here):

$PostedVar = mysqli_real_escape_string($_POST['userinput']);
$CommaCount = substr_count($UserString, ','); 
$ExplodedUserString = explode(",", $UserString);
$Break = 'nobreak';

$i = 1;  
foreach ($ExplodedUserString as $EUS) {
    $Current = $EUS;
    if ($i > $CommaCount) {
        break;
    }
    else if ($Current === $PostedVar) {
        $Break = 'break';
        break;
    }
    else {            
        $i++;
    }
}//End foreach

if ($Break === 'break') {
    echo "<script>
    alert ('You have previously selected "'.$PostedVar.'". Please try again!');
    location = 'home.php';
    </script>"        
}
else {
    echo "<script>
    alert ('Thanks for selecting "'.$PostedVar.'"!');
    location = 'home.php';
    </script>";
}

I then compared foreach vs. in_array to check $UserString by doing everything exactly the same except adding 2 microtime statements as follows for both foreach and in_array:

//foreach method
$time1 = microtime();
$i = 1;  
foreach ($ExplodedUserString as $EUS) {
    $Current = $EUS;
    if ($i > $CommaCount) {
        break;
    }
    else if ($Current === $PostedVar) {
        $Break = 'break';
        break;
    }
    else {

        $i++;
    }
}//End foreach

$time2 = microtime();
$Diff = $time2 - $time1;

if ($Break === 'break') {
    echo "<script>
    alert ('$Diff');
    location = 'home.php';
    </script>"        
}
else {
    echo "<script>
    alert ('$Diff');
    location = 'home.php';
    </script>";
}

versus:

//in_array method
$time1 = microtime();
if (in_array($PostedVar, $ExplodedUserString)) {
    $Break = 'break';
}
$time2 = microtime();
$Diff = $time2 - $time1;

if ($Break === 'break') {
    echo "<script>
    alert ('$Diff');
    location = 'home.php';
    </script>"        
}
else {
    echo "<script>
    alert ('$Diff');
    location = 'home.php';
    </script>";
}

I did 9 trials where all factors were kept constant (clicked same submit button, same user, same $UserString, etc.) and threw out the high and low values...the mean of $Diff with 7 trials for both foreach and in_array was actually faster by 12% for in_array. Keep in mind this is for a short string of only 5 comma-separated values for $UserString. Especially for larger strings, wouldn't in_array be faster than a foreach loop? The importance for my site is that I anticipate typical $UserString values to have at least 10-20 times more characters than the $UserString I used to test.

  • 写回答

1条回答 默认 最新

  • douqian5920 2014-01-17 19:18
    关注

    Since you're exploding in both scenarios, you might consider just exploding to a key value pair and doing a simple isset on the key you're looking for. I can't say what the performance would be, and without having viewed PHP source, I'd say in_array probably do it's own foreach.

    Just a link to consider:

    explode() into $key=>$value pair

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题