Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

in_array() performance optimization

I have the following condition:

if(in_array($needle, $haystack) ||
    in_array($needle . "somePostfix", $haystack) ||
    in_array($needle . "someOtherPostfix", $haystack) ||
    // and some more) {
    // do something
}

My haystack contains more than 10k elements, and this check takes about 400ms. I know that in_array has to iterate over the whole array multiple times. In my case the common case is that the element is not found. and I tried to improve this by creating the following method that only iterates once over the haystack:

function wildcardInArray($needle, $haystack) {
    foreach ($haystack as $value) {
        if (true === fnmatch($needle . '*', $haystack)) {
            return true;
        }
    }
    return false;
}

But this decreases my performance even more, seems to me that fnmatch is the bottleneck.

Is there any improvement for this case of array search?

like image 640
bpoiss Avatar asked Feb 04 '16 15:02

bpoiss


People also ask

Is In_array fast?

PHP's in_array() function is really slow.

What is the use of In_array () function?

The in_array() function is an inbuilt function in PHP that is used to check whether a given value exists in an array or not. It returns TRUE if the given value is found in the given array, and FALSE otherwise.


1 Answers

You can use your array as 'keys', i.e:

$arr = ['a', 'b', 'c', … ]; to $arr = ['a' => true, 'b' => true, …].

You will consume more memory but you will have an instant result with isset($arr[$key]);.

Fastest but biggest in memory, you can use stdClass and isset($obj->$key);

$obj = new stdClass();
$obj->{'a'} = true;
$obj->{'b'} = true;
$obj->{'…'} = true;

If you can't change your array structure, tell us if you can sort manually the array contents?

// generic
$length = strlen($needle);
$char = $needle[0];
$found = false;
$suffixes = [ false, 'somePostfix', 'someOtherPostfix' ];

foreach($haystack as $entry) {
  if ($char === $entry[0] && $needle === substr($entry, 0, $length)) {
    $suffix = substr($entry, $length);
    if (in_array($suffix, $suffixes, true)) {
      $found = true;
      break;
    }
  }
}
like image 124
C Würtz Avatar answered Sep 23 '22 17:09

C Würtz