what is faster: in_array or isset? [closed]

瘦欲@ 提交于 2019-11-26 14:27:37

The answers so far are spot-on. Using isset in this case is faster because

  • It uses an O(1) hash search on the key whereas in_array must check every value until it finds a match.
  • Being an opcode, it has less overhead than calling the in_array built-in function.

These can be demonstrated by using an array with values (10,000 in the test below), forcing in_array to do more searching.

isset:    0.009623
in_array: 1.738441

This builds on Jason's benchmark by filling in some random values and occasionally finding a value that exists in the array. All random, so beware that times will fluctuate.

$a = array();
for ($i = 0; $i < 10000; ++$i) {
    $v = rand(1, 1000000);
    $a[$v] = $v;
}
echo "Size: ", count($a), PHP_EOL;

$start = microtime( true );

for ($i = 0; $i < 10000; ++$i) {
    isset($a[rand(1, 1000000)]);
}

$total_time = microtime( true ) - $start;
echo "Total time: ", number_format($total_time, 6), PHP_EOL;

$start = microtime( true );

for ($i = 0; $i < 10000; ++$i) {
    in_array(rand(1, 1000000), $a);
}

$total_time = microtime( true ) - $start;
echo "Total time: ", number_format($total_time, 6), PHP_EOL;

Which is faster: isset() vs in_array()

isset() is faster.

While it should be obvious, isset() only tests a single value. Whereas in_array() will iterate over the entire array, testing the value of each element.

Rough benchmarking is quite easy using microtime().

Results:

Total time isset():    0.002857
Total time in_array(): 0.017103

Note: Results were similar regardless if existed or not.

Code:

<?php
$a = array();
$start = microtime( true );

for ($i = 0; $i < 10000; ++$i) {
    isset($a['key']);
}

$total_time = microtime( true ) - $start;
echo "Total time: ", number_format($total_time, 6), PHP_EOL;

$start = microtime( true );

for ($i = 0; $i < 10000; ++$i) {
    in_array('key', $a);
}

$total_time = microtime( true ) - $start;
echo "Total time: ", number_format($total_time, 6), PHP_EOL;

exit;

Additional Resources

I'd encourage you to also look at:

Ja͢ck

Using isset() takes advantage of speedier lookup because it uses a hash table, avoiding the need for O(n) searches.

The key is hashed first using the djb hash function to determine the bucket of similarly hashed keys in O(1). The bucket is then searched iteratively until the exact key is found in O(n).

Barring any intentional hash collisions, this approach yields much better performance than in_array().

Note that when using isset() in the way that you've shown, passing the final values to another function requires using array_keys() to create a new array. A memory compromise can be made by storing the data in both the keys and values.

Update

A good way to see how your code design decisions affect runtime performance, you can check out the compiled version of your script:

echo isset($arr[123])

compiled vars:  !0 = $arr
line     # *  op                           fetch      ext  return  operands
-----------------------------------------------------------------------------
   1     0  >   ZEND_ISSET_ISEMPTY_DIM_OBJ              2000000  ~0      !0, 123
         1      ECHO                                                 ~0
         2    > RETURN                                               null

echo in_array(123, $arr)

compiled vars:  !0 = $arr
line     # *  op                           fetch      ext  return  operands
-----------------------------------------------------------------------------
   1     0  >   SEND_VAL                                             123
         1      SEND_VAR                                             !0
         2      DO_FCALL                                 2  $0      'in_array'
         3      ECHO                                                 $0
         4    > RETURN                                               null

Not only does in_array() use a relatively inefficient O(n) search, it also needs to be called as a function (DO_FCALL) whereas isset() uses a single opcode (ZEND_ISSET_ISEMPTY_DIM_OBJ) for this.

The second would be faster, as it is looking only for that specific array key and does not need to iterate over the entire array until it is found (will look at every array element if it is not found)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!