what is faster: in_array or isset?
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: in_array() or a bunch of expressions in PHP?
i'd strongly suggest just using in_array()
, any speed difference would be negligible, but the readability of testing each variable separately is horrible.
just for fun here's a test i ran:
$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
slightly trivial note to watch for, if $var
is not set, method 1 takes much longer (depending on how many conditions you test)
Update for newer PHP versions:
Martijn: I'ved extended the array to five elements, and look for test3
, as sort of an average case.
PHP5.6
Time1: 0.20484399795532
Time2: 0.29854393005371
PHP7.1
Time1: 0.064045906066895
Time2: 0.056781053543091
PHP7.4
Time1: 0.048759937286377
Time2: 0.049691915512085
PHP8.0
Time1: 0.045055150985718
Time2: 0.049431085586548
Conclusion: The original test wasnt the best test, and also: In php7+ is has become a matter of preference.
in_array() performance optimization
This is a very interesting question that doesn't appear to have a great answer. I did some very unscientific bench-marking and I was not able to get any faster than in_array
for a $haystack
with 100000 elements.
PHP 5.5.9-1ubuntu4.14 (cli) (built: Oct 28 2015 01:34:46)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies
with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans
Sorting Time*: 0.19367408752441
Imploding Time**: 0.0207359790802
preg_match: 0.10927486419678
needle ===: 0.083639144897461
in_array: 0.019428968429565
array_flip: 0.028955936431885
array_intersect: 0.15198707580566
array_diff: 0.15532493591309
//*sort without search (binary search wouldn't add much time)
//**time it took to implode the array
// (no search was performed, this search WOULD take significant time if implemented)
As you can see, only three of these methods took less than 100ms, needle ===
, in_array
and array_flip
. And out of these three, in_array
was clearly the fastest. Now the question is how many postfix-es do you have? The running time on in_array
will be O(n*m)
(n
is size of your haystack, m
is the number of postfixes), which is a problem if m
is also very large. If m
is significantly large, sorting the data once and performing a binary search on the sorted list will be O(m*log(n))
which grows much slower, but has a higher initial overhead as shown in the sorting time above. Even better, if you have a very large m
would probably be array_flip
as each search should only take O(1)
lookup after the initial flip.
CODE
Haystack creation
$haystack = array();
function getRandomWord($len = 10) {
$len = rand(3,10);
$word = array_merge(range('a', 'z'), range('A', 'Z'));
shuffle($word);
return substr(implode($word), 0, $len);
}
$numWords = 100000;
for($i = 0; $i < $numWords; $i++) {
$haystack[] = getRandomWord();
}
TESTs
//*Sorting*
$copy = $haystack;
sort($copy);
//implode
$copy = implode($haystack, " ");
//*preg_match_test*
function preg_match_test($regex, $haystack) {
$matches = false;
foreach($haystack as $value) {
if (preg_match($regex, $value)) {
$matches = true;
break;
}
}
return $matches;
}
//needle ===
function equalsNeedle($needles, $haystack) {
$matches = false;
foreach ($haystack as $value) {
foreach($needles as $needle) {
if ($needle === $value) {
$matches = true;
break 2;
}
}
}
return $matches;
}
//in_array
function baseCase($needles, $haystack) {
$matches = false;
foreach($needles as $needle) {
if (in_array($needle, $haystack)) {
$matches = true;
break;
}
}
return $matches;
}
//array_flip
function arrayFlipping($needles, $haystack) {
$matches = false;
$copy = array_flip($haystack);
foreach ($needles as $needle) {
if (array_key_exists($needle, $copy)) {
$matches = true;
}
}
return $matches;
}
//array_intersect
function arrayIntersect($needles, $haystack) {
if (count(array_intersect($needles, $haystack)) > 0) {
return true;
}
return false;
}
//array_diff
function arrayDiff($needles, $haystack) {
if (count(array_diff($needles, $haystack)) !== count($needles)) {
return true;
}
return false;
}
Calling Code
$array = array("foo","foobar","foobazz","foobuzz");
$base = "foo";
$regex = "/^$base(bizz|bazz|buzz|)$/";
echo "preg_match: ";
preg_match_test($regex, $haystack);
echo "needle === ";
equalsNeedle($array, $haystack);
echo "in_array: ";
baseCase($array, $haystack);
echo "array_flip: ";
arrayFlipping($array, $haystack);
echo "array_intersect: ";
arrayIntersect($array, $haystack);
echo "array_diff: ";
arrayDiff($array, $haystack);
All tests were wrapped with timing code using microtime(true)
.
Faster to use in_array() or large if-conditional?
The build-in function are always faster, as they are compiled C code. The PHP code must be interpreted.
If you really care about CPU cycles, isset() is fastest, so setting the possible values as array keys will be fastest way. Of course, there is CPU vs memory usage, so which use less system resources depends on which resources you want to save.
As @Kendall Frey stated, this is micro-optimization, so keep code readable and don't do anything about optimization, unless profiler shows that this code has large impact on the execution.
in_array vs strpos for performance in php
strpos
is the fastest way to search a text needle, per the php.net documentation for strstr()
:
If you only want to determine if a particular needle occurs within haystack, use the faster and less memory intensive function strpos() instead.1
Related Topics
PHP Error: Cannot Modify Header Information - Headers Already Sent
Utf-8 Bom Signature in PHP Files
Continue PHP Execution After Sending Http Response
Filter Multidimensional Array Based on Partial Match of Search Value
Does File_Get_Contents() Have a Timeout Setting
PHP Pdo: Get the Columns Name of a Table
PHP Class Instantiation. to Use or Not to Use the Parentheses
Creating PHP Class Instance With a String
.Htaccess Rewrite Get Variables