7

I have code that adds values to an array. The array is later searched in another part of my code. The values that are added to the array are not necessarily unique, so it's possible to end up with duplicate values in the array being searched. Technically speaking, even with the duplicates present in the array being searched, my code works fine and I'll be able to find the value. I just want to know if the value is in the array being searched, and don't care if it's in the array 1 time or 10,000 times.

My question is whether it's preferred (for performance and/or style reasons) to do array_unique() on my array being searched before I do the search.

So for example, suppose I want to search an array like this:

$searchMe = Array("dog", "cat", "mouse", "dog", "dog", "dog");

Note that "dog" is present 4 times. If I want to search for the value "dog", in that array, it will work fine and I will be able to tell that it's present. As mentioned above, I don't care how many times it's present, I just want to know if it's present at all.

So should I do this first before searching and then search against the de-duped array?

$searchMe_cleaned = array_unique($searchMe);

I.e., will that be faster than just searching the array with the duplicates?

Please keep in mind that although in this example the array being searched just has a few elements, the real array being searched could have hundreds or thousands of elements.

Thanks!

Travitron
  • 593
  • 6
  • 11

3 Answers3

12

I think array_unique is slower than in_array but it makes sense if you want to search the array more than one time or if you want to save memory.

Another option is to use array_flip (which will also drop duplicate keys) and then use isset or array_key_exists since they are way faster than in_array, personally I would go this way.

Alix Axel
  • 151,645
  • 95
  • 393
  • 500
  • Great suggestion! I love how array_flip intrinsically removes duplicates while also allow you to use the faster isset() function. – Travitron Feb 19 '11 at 19:51
  • 11
    Just found that `array_keys(array_flip($array));` is amazingly faster than `array_unique();`. About 80% faster on 100 element array, 95% faster on 1000 element array and 99% faster on 10000+ element array. – Carlos Jan 17 '13 at 08:40
  • @Carlos I just found out the same thing so I can confirm that this technique works perfect! – Szymon Sadło Jul 12 '16 at 09:28
  • Please also note that `array_keys(array_flip($array))` is faster only for integers. See http://net-beta.net/ubench/index.php?t=array11 and http://net-beta.net/ubench/index.php?t=array13 for benchmarks – Szymon Sadło Jul 12 '16 at 11:47
12

This comment was worthy to be promoted to an answer:

Just found that array_keys(array_flip($array)); is amazingly faster than array_unique();. About 80% faster on 100 element array, 95% faster on 1000 element array and 99% faster on 10,000+ element array.

Testing here shows that with random (integer) strings which do contain array value repetition, that array_keys(array_flip($array)); method is orders of magnitude faster than other methods.

Martin
  • 22,212
  • 11
  • 70
  • 132
  • 1
    I added one more into this, `array_flip(array_flip($array));`, whose performance is [at par with array_keys/array_flip](http://sandbox.onlinephpfunctions.com/code/21795cfd0a70e714760ff2666e8bc38c58653002). Sometimes one is faster, sometimes the other one - but of course both of them always faster than the other alternatives. – Jay Dadhania Apr 30 '20 at 06:14
  • that sandbox is showing the opposite for me: ```** array_unique Time spent on 5000 : 0.00035905838012695 ** array_flip / keys Time spent on 5000 : 8.4877014160156E-5``` – Brad Feb 08 '23 at 05:24
  • @Brad what version PHP is that on? – Martin Feb 08 '23 at 10:46
  • 8.2.1. I'm just using the link in the answer and clicking execute. – Brad Feb 09 '23 at 22:05
3

array_unique is about sqrt(n) times slower then in_array. But if you optimize the data and search again many times, it can be worth

PS: notice that

isset($arr[$key])

works faster then in_array providing the same result

Dan
  • 55,715
  • 40
  • 116
  • 154