哪个更快:in_array()或PHP中的一堆表达式?

时间:2008-11-27 21:17:24

标签: php arrays if-statement

执行以下操作会更快:

 if ($var != 'test1' && $var != 'test2' && $var != 'test3' && $var != 'test4') { ... }

或者:

 if (!in_array($var, array('test1', 'test2', 'test3', 'test4') { ... }

是否存在多个值,在这一点上做一个或另一个更快?

(在这种情况下,第二个选项中使用的数组不存在。)

10 个答案:

答案 0 :(得分:16)

我强烈建议只使用in_array(),任何速度差异都可以忽略不计,但分别测试每个变量的可读性非常糟糕。

这里只是为了好玩,我跑了一个测试:

$array = array('test1', 'test2', 'test3', 'test4');
$var = 'test';
$iterations = 1000000;

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if ($var != 'test1' && $var != 'test2' && $var != 'test3' && $var != 'test4') {}
}
$end = microtime(true);

print "Time1: ". ($end - $start)."<br />";

$start2 = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if (!in_array($var, $array) ) {}
}
$end2 = microtime(true);

print "Time2: ".($end2 - $start2)."<br />";

// Time1: 1.12536692619
// Time2: 1.57462596893

值得注意的是,如果未设置$var,则方法1需要更长的时间(取决于您测试的条件数)

答案 1 :(得分:7)

请注意,如果您要替换一堆!==语句,则应将第三个参数作为true传递给in_array,这会强制对!=中的项进行类型检查。阵列。

普通{{1}}显然不需要这个。

答案 2 :(得分:6)

第一个会更快 - 第二个会有很多开销:创建数组,调用函数,搜索数组......

然而,正如我在一个问题中所说的几个答案,过早的优化是所有邪恶的根源。您应该将代码编写为可读,然后如果需要对其进行优化配置,然后进行优化。

编辑:

我的时间与@ Owen的代码(PHP 5.2.6 / windows):

Time1: 1.33601498604
Time2: 4.9349629879

在循环中移动数组(...),如问题所示:

Time1: 1.34736609459
Time2: 6.29464697838

答案 3 :(得分:2)

对于大量项目,

in_array会更快。基于与数据和计算机相关的许多因素,“大”是非常主观的。既然你在询问,我认为你不是在处理一些微不足道的事情。对于更长的列表,注意this information,并使用翻转的数组测量性能,以便php可以利用哈希查找而不是线性搜索。对于“静态”数组,调整可能无法提高性能,但也可能。

使用Owen的测试代码,使用翻转数组和更多迭代来获得更一致的结果:

$array2 = array_flip($array);
$iterations = 10000000;

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if (!isset($array2[$var])) {}
}
$end = microtime(true);
print "Time3: ".($end - $start)."<br />";

Time1: 12.875
Time2: 13.7037701607
Time3: 3.70514011383

答案 4 :(得分:2)

您好我刚才把这个案例推向极端,并指出随着数量越来越多,简单比较是最高效的方式。

这是我的代码:

$var = 'test';
$num_values = 1000;
$iterations = 1000000;
print "\nComparison performance test with ".$num_values." values and ".$iterations." loop iterations";
print "\n";

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if ($var != 'test0' &&
        $var != 'test1' &&
        // ...
        // yes I really have 1000 lines in my file
        // ...
        $var != 'test999') {}
}
print "\nCase 1: plain comparison";
print "\nTime 1: ". (microtime(true) - $start);
print "\n";

$start = microtime(true);
$array = array();
for($i=0; $i<$num_values; $i++) {
    $array1[] = 'test'.$i;
}
for($i = 0; $i < $iterations; ++$i) {
    if (!in_array($var, $array1) ) {}
}
print "\nCase 2: in_array comparison";
print "\nTime 2: ".(microtime(true) - $start);
print "\n";

$start = microtime(true);
$array = array();
for($i=0; $i<$num_values; $i++) {
    $array2['test'.$i] = 1;
}
for($i = 0; $i < $iterations; ++$i) {
    if (!isset($array2[$var])) {}
}
print "\nCase 3: values as keys, isset comparison";
print "\nTime 3: ".(microtime(true) - $start);
print "\n";

$start = microtime(true);
$array = array();
for($i=0; $i<$num_values; $i++) {
    $array3['test'.$i] = 1;
}
for($i = 0; $i < $iterations; ++$i) {
    if (!array_key_exists($var, $array3)) {}
}
print "\nCase 4: values as keys, array_key_exists comparison";
print "\nTime 4: ".(microtime(true) - $start);
print "\n";

我的结果(PHP 5.5.9):

Case 1: plain comparison
Time 1: 31.616894006729

Case 2: in_array comparison
Time 2: 23.226133823395

Case 3: values as keys, isset comparison
Time 3: 0.050863981246948

Case 4: values as keys, array_key_exists comparison
Time 4: 0.13700890541077

我同意,这有点极端,但它显示了PHP的哈希表式关联数组的大局和巨大潜力,你只需要使用它

答案 5 :(得分:1)

请注意,正如RoBorg指出的那样,创建数组会产生开销,因此应该在迭代循环中移动它。出于这个原因,Sparr的帖子也有点误导,因为array_flip函数会产生开销。

以下是另外一个包含所有5种变体的示例:

$array = array('test1', 'test2', 'test3', 'test4');
$var = 'test';
$iterations = 1000000;

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
   if ($var != 'test1' && $var != 'test2' && $var != 'test3' && $var != 'test4') {}
}
print "Time1: ". (microtime(true) - $start);

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
   if (!in_array($var, $array) ) {}
}
print "Time2: ".(microtime(true) - $start);

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
   if (!in_array($var, array('test1', 'test2', 'test3', 'test4')) ) {}
}
print "Time2a: ".(microtime(true) - $start);

$array2 = array_flip($array);
$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
  if (!isset($array2[$var])) {}
}
print "Time3: ".(microtime(true) - $start);

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    $array2 = array_flip($array);
  if (!isset($array2[$var])) {}
}
print "Time3a: ".(microtime(true) - $start);

我的结果:

Time1 : 0.59490108493 // straight comparison
Time2 : 0.83790588378 // array() outside loop - not accurate
Time2a: 2.16737604141 // array() inside loop
Time3 : 0.16908097267 // array_flip outside loop - not accurate
Time3a: 1.57209014893 // array_flip inside loop

总之,使用array_flip(使用isset)比使用inarray更快但不如直接比较快。

答案 6 :(得分:1)

谈到PHP,并询问是否:

  • 一组&#34; if&#34; s&#34; else ifs&#34; ,
  • a&#34; if&#34;使用一组&#34;或&#34; ed条件(如原始帖子详细信息中所示)或
  • 使用&#34; in_array&#34;使用动态构造的数组,

更好,

应该记住PHP语言&#34;切换&#34;声明是针对此类情况设计的替代方案,可能是更好的答案。 (虽然海报的例子让我们只是比较两个解决方案,实际的问题标题要求考虑in_array与PHP语句,所以我认为这是公平的游戏。)

在海报的例子中,我建议:

{sdfsdfsdfsdfsdf}
{sdfsdfsdfsfsdfsdf}
{dfsdfsdfsdfsdfsf}
{dfsdfsdfsfsdfsd}

我希望PHP允许在这些情况下使用几个非原始结构,例如用于&#34;或&#34;的逗号。但以上是PHP的设计者认为是最清晰的处理方式。并且它在执行时似乎比其他两个替代方案更有效。

只要我在谈论愿望清单,&#34; IN&#34;在海报的示例情况下,在SQL中找到的内容会更加清晰。

这种想法可能导致人们想要使用&#34; in_array&#34;,对于这种情况,但是不得不构建数据结构然后使用为该数据结构设计的谓词是很不幸的。 ,而不是没有办法在没有开销的情况下说出来。

答案 7 :(得分:1)

此处是此工作台的实时更新,其中还有另一种案例https://3v4l.org/OA2S7

PHP 7.3的结果:

  • 多个比较: 0.0575 07991790771

  • in_array: 0.0256 8507194519

  • array_flip()外循环测量+ isset(): 0.0146 78001403809

  • array_flip()外循环未测量+ isset(): 0.0156 50033950806

  • foreach和比较: 0.0627 82049179077

答案 8 :(得分:0)

我知道这个问题已有近10年的历史,但还有其他方法可以解决这个问题。我使用Nick's page中的方法B和数千个条目。它的速度非常快。

foreach(array_values($haystack) as $v)
    $new_haystack[$v] = 1; 
}

// So haystack becomes:
$arr[“String1”] = 1;
$arr[“String2”] = 1;
$arr[“String3”] = 1;


// Then check for the key:
if (isset($haystack[$needle])) {
    echo("needle ".$needle." found in haystack");
}

答案 9 :(得分:0)

我的测试

$array = array('test1', 'test2', 'test3', 'test4');
$var = 'test';
$iterations = 1000000;

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if ($var != 'test1' && $var != 'test2' && $var != 'test3' && $var != 'test4') {}
}
$end = microtime(true);

print "Time1: ". ($end - $start)."<br />";

$start2 = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if (!in_array($var, $array) ) {}
}
$end2 = microtime(true);

print "Time2: ".($end2 - $start2)."<br />";

$array_flip = array_flip($array);

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if (!isset($array_flip[$var])) {}
}
$end = microtime(true);
print "Time3: ".($end - $start)."<br />";

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if (!isset($array[$var])) {}
}
$end = microtime(true);

print "Time4: ". ($end - $start)."<br />";
  

时间1:0.20001101493835

     

Time2:0.32601881027222

     

Time3:0.072004079818726

     

Time4:0.070003986358643