Which is faster: in_array() or a bunch of expressions in PHP?

Question!

Is it faster to do the following:

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

Or:

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

Is there a number of values at which point it's faster to do one or the other?

(In this case, the array used in the second option doesn't alreay exist.)



Answers

When speaking of PHP, and asking whether:

  • a set of "if"s and "else ifs" ,
  • an "if" with a set of "or"ed conditions (as in the original post details) , or
  • use of "in_array" with an on-the-fly constructed array ,

is better,

one should keep in mind that the PHP language "switch" statement is an alternative designed for such situations and may be a better answer. (Although the poster's example leads us to just comparing two solutions, the actual question heading asks to consider in_array versus PHP statements, so I think this is fair game).

In the poster's example, then, I would instead recommend:

switch ($var)
{ case 'test1': case 'test2': case 'test3': case 'test4':
     echo "We have a good value"; break;
  default:
     echo "We do not have a good value";
}

I wish PHP allowed for a couple of non-primitive constructs in the cases, such as a comma for "or". But the above is what the designers of PHP considered to be the clearest way of handling this. And it appears to be more efficient at execution time than the other two alternatives, as well.

As long as I'm talking about a wishlist, the "IN" found in SQL would be even clearer for the poster's example situation.

This thinking is probably what leads to people wanting to use "in_array", for such situations, but it is kind of unfortunate to have to build a data structure and then use a predicate designed for that data structure, rather than having a way to just say it without that overhead happening.



Hi I just took this case to extremes and pointed out that with increasing number of values plain comparison is not the most performant way.

Here is my code:

$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";

My Results (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

I agree, thats a little extreme but it shows the big picture and the great potential in the hash-table-like associative arrays of PHP, you just have to use it



This video can help you solving your question :)
By: admin