-
-
Save Thinkscape/1965669 to your computer and use it in GitHub Desktop.
<?php | |
if(!isset($argv[1])){ | |
echo "Usage: ".$argv[0]." (number of iterations)\n"; | |
exit(1); | |
} | |
/** | |
* Arrays to check | |
*/ | |
$tests = array( | |
array(array( | |
'foo' => 'bar', | |
)), | |
array(array( | |
'bar', | |
'foo' => 'bar', | |
'baz', | |
)), | |
array(null), | |
array(true), | |
array(false), | |
array(0), | |
array(1), | |
array(0.0), | |
array(1.0), | |
array('string'), | |
array(array(0, 1, 2)), | |
array(new stdClass), | |
array_fill(0,1000,uniqid()), // big numeric array | |
array_fill_keys(range(2,1000,3),uniqid()), // big misaligned numeric array (=associative) | |
array_fill_keys( // big associative array | |
str_split( | |
str_repeat(uniqid('',true),100), | |
3 | |
), | |
true | |
) | |
); | |
$iterations = (int)$argv[1]; | |
/** | |
* Common methods to check associative array | |
*/ | |
$methods = array( | |
'method1 (array_values check)' => | |
function($array){ | |
return (array_values($array) !== $array); | |
}, | |
'method2 (array_keys comparison)' => | |
function($array){ | |
$array = array_keys($array); return ($array !== array_keys($array)); | |
}, | |
'method3 (array_filter of keys)' => | |
function($array){ | |
return count(array_filter(array_keys($array), 'is_string')) > 0; | |
} | |
); | |
/** | |
* Perform benchmark on each method | |
*/ | |
foreach($methods as $name=>$func){ | |
echo "Testing $name - $iterations iterations\n"; | |
$time = microtime(true); | |
for($x=0;$x<$iterations;$x++){ | |
foreach($tests as $array){ | |
$func($array); | |
} | |
} | |
/** | |
* Show results | |
*/ | |
$totalTime = (microtime(true) - $time); | |
$avgTime = $totalTime / ($iterations * count($tests)); | |
echo " Total time: ".number_format($totalTime,5,'.',' ')." s\n"; | |
echo " Average : ".number_format($avgTime*1000,5,'.',' ')." ms / test \n"; | |
echo "\n"; | |
} | |
From PHPTester
PHP 5.5
Testing method1 (array_values check) - 10000 iterations
Total time: 0.85214 s
Average : 0.00568 ms / test
Testing method2 (array_keys comparison) - 10000 iterations
Total time: 1.57167 s
Average : 0.01048 ms / test
Testing method3 (array_filter of keys) - 10000 iterations
Total time: 2.99962 s
Average : 0.02000 ms / test
Testing method4 (foreach typecast) - 10000 iterations
Total time: 1.11735 s
Average : 0.00745 ms / test
PHP 5.6
Testing method1 (array_values check) - 10000 iterations
Total time: 1.00357 s
Average : 0.00669 ms / test
Testing method2 (array_keys comparison) - 10000 iterations
Total time: 1.77896 s
Average : 0.01186 ms / test
Testing method3 (array_filter of keys) - 10000 iterations
Total time: 3.71037 s
Average : 0.02474 ms / test
Testing method4 (foreach typecast) - 10000 iterations
Total time: 1.34244 s
Average : 0.00895 ms / test
PHP 7.0
Testing method1 (array_values check) - 10000 iterations
Total time: 0.23163 s
Average : 0.00154 ms / test
Testing method2 (array_keys comparison) - 10000 iterations
Total time: 0.30419 s
Average : 0.00203 ms / test
Testing method3 (array_filter of keys) - 10000 iterations
Total time: 0.60409 s
Average : 0.00403 ms / test
Testing method4 (foreach typecast) - 10000 iterations
Total time: 0.56797 s
Average : 0.00379 ms / test
Method 1 is even more faster with PHP 7.2:
Testing method1 (array_values check) - 10000 iterations
Total time: 0.02857 s
Average : 0.00019 ms / test (!)
Testing method2 (array_keys comparison) - 10000 iterations
Total time: 0.19137 s
Average : 0.00128 ms / test
Testing method3 (array_filter of keys) - 10000 iterations
Total time: 0.48394 s
Average : 0.00323 ms / test
Testing method4 (foreach typecast) - 10000 iterations
Total time: 0.41342 s
Average : 0.00276 ms / test
Hi, I just came with an idea of a is_associative_array function if you are still open to contributions:
<?php
function is_associative_array( array &$a ): bool {
$l = count( $a );
for ( $i = 0; $i < $l; $i++ ) {
if ( key( $a ) !== $i ) {
return true;
}
next( $a );
}
return false;
}
Tell me about it!
Hi, I just came with an idea of a is_associative_array function if you are still open to contributions:
<?php function is_associative_array( array &$a ): bool { $l = count( $a ); for ( $i = 0; $i < $l; $i++ ) { if ( key( $a ) !== $i ) { return true; } next( $a ); } return false; }
Tell me about it!
i just tested your method and it is way worse than all others... sorry :)
source: https://gist.github.com/oriadam/5e8424608fb3f8d70ec3e9ae344dbf8f
Testing 10000 iterations on PHP version 7.3.25
if (array_key_first($array)!==0) return true; return array_values($array) !== $array;
Total time: 0.26179 s
Average : 0.00175 ms / test
return array_values($array) !== $array;
Total time: 0.23978 s
Average : 0.00160 ms / test
return range(0,count($array)) !== array_keys($array);
Total time: 0.44664 s
Average : 0.00298 ms / test
return array_keys($array); return ($array !== array_keys($array));
Total time: 0.50882 s
Average : 0.00339 ms / test
return count(array_filter(array_keys($array), "is_string")) > 0;
Total time: 3.99202 s
Average : 0.02661 ms / test
foreach...$i++
Total time: 1.23879 s
Average : 0.00826 ms / test
for...key...next
Total time: 7.73038 s
Average : 0.05154 ms / test
check this out:
$methods = [
// [...]
'method4 (revision of method1, with php8.1 fn)' =>
function ($array) {
return (array_is_list($array) === false);
},
'method5 (json_encode output parsing with array_is_list - php>=8.1)' =>
static function ($array) {
// consider empty, and [0, 1, 2, ...] sequential
if (empty($array) || array_is_list($array)) {
return false;
}
// first scenario:
// [ 1 => [*any*] ]
// [ 'a' => [*any*] ]
foreach ( $array as $key => $value ) {
if (is_array($value)) {
return true;
}
}
// second scenario: read the json string
$jsonNest = json_encode($array, JSON_THROW_ON_ERROR);
return str_contains($jsonNest, '{');
},
'method6 (json_encode output parsing - php=8.0)' =>
static function ($array) {
if (empty($array) || array_values($array) !== $array) { return false; }
foreach ( $array as $key => $value ) { if (is_array($value)) { return true; } }
$jsonNest = json_encode($array, JSON_THROW_ON_ERROR);
return str_contains($jsonNest, '{');
},
];
Results
Testing method1 (array_values check) - 10000 iterations
Total time: 0.60444 s
Average : 0.00403 ms / test
Testing method2 (array_keys comparison) - 10000 iterations
Total time: 0.32689 s
Average : 0.00218 ms / test
Testing method3 (array_filter of keys) - 10000 iterations
Total time: 2.22523 s
Average : 0.01483 ms / test
Testing method4 (revision of method1, with php8.1 fn) - 10000 iterations
Total time: 0.09834 s
Average : 0.00066 ms / test
Testing method5 (json_encode output parsing with array_is_list - php>=8.1) - 10000 iterations
Total time: 0.47469 s
Average : 0.00316 ms / test
Testing method6 (json_encode output parsing - php<=8.0) - 10000 iterations
Total time: 1.01134 s
Average : 0.00674 ms / test
Anyone curious about the benchmark without the static closure?
Testing method5 (json_encode output parsing with array_is_list - php>=8.1) - 10000 iterations
Total time: 1.08914 s
Average : 0.00726 ms / test
Testing method6 (json_encode output parsing - php=8.0) - 10000 iterations
Total time: 4.92953 s
Average : 0.03286 ms / test
They are much slower!
other methods perform the same instead. Somebody can explain me why?
PHP 7.1.4