The fastest way to select the Nth hash element

I have a large hash table (an array with string indexes) and search for a function that quickly selects the first (ideally, and Nth) element from it. array_shift() and reset() too slow for my needs.

UPDATE : I am also not looking for a reference solution, the function should accept expressions as in get_first(some_func_returning_array())

The ANSWER method array_slice (kudos Gumbo) seems to be the winner. Full test code

 function bigary($n) { $a = array(); $s = range('A', 'Z'); do { shuffle($s); $a[substr(implode('', $s), rand(10, 20))] = $n; } while(--$n); return $a; } function timeit($name, $fn) { global $results; $loops = 1000; $size = 5432; static $a; if(!$a) $a = bigary($size); $t = microtime(1); for($i = 0; $i < $loops; $i++) $b = $fn($a); $results[$name] = microtime(1) - $t; } timeit('dummy', function ($a) { // benchmark php function call overhead }); timeit('array_shift', function ($a) { return array_shift($a); }); timeit('reset', function ($a) { return reset($a); }); timeit('foreach', function ($a) { foreach($a as $b) return $b; }); timeit('keys', function ($a) { $b = array_keys($a); return $a[$b[0]]; }); timeit('values', function ($a) { $b = array_values($a); return $b[0]; }); timeit('slice', function ($a) { $b = array_slice($a, 0, 1); return reset($b); }); asort($results); foreach($results as $name => $time) printf("%20s = %.3f\n", $name, $time); 

Results:

  dummy = 0.393 slice = 0.433 values = 0.824 foreach = 0.929 reset = 0.935 array_shift = 0.954 keys = 1.371 
+6
source share
5 answers

Use array_slice to get an array of only the nth element and array_pop to finally get it:

 $nthItem = array_pop(array_slice($arr, $n, 1)); 
+7
source

Your test may be wrong because:

 $fn = function ($a) { return array_shift($a); }; timeit('array_shift', $fn); 

array_shift = 1.242 (5432)

and

 timeit('array_shift', array_shift); 

array_shift = 0.026 (4433)

but also

 $fn = function ($a) { } timeit('empty lambda', $fn); 

empty lambda = 0.501 (0)

However, another possible solution:

 $v = array_values($a); return $v[ $index ]; 

Code example:

 $t = microtime(1); $v = array_values($a); // cached while($loops--) { $b = $v[$loops]; } 

array_values ​​= 0.002 (5432)

+4
source

I don't think you can get faster than reset() / end() for the first / last element.

As for the Nth element, I can't think of anything better than this:

 function (&$hashmap, $n) { $keys = array_keys($hashmap); return $hashmap[$keys[$n]]; } 

Of course, for performance, this might tune in to having a cached $keys array (unless hashmap changes very often). In this case, it is possible that even extracting elements from the 0th element may be faster than with reset()

+2
source

To get the first:

 function array_first(array $array) { foreach ($array as $value) return $value; return false; } 

And although I have not tested this for speed, you can try using array_values() to convert the array to a numerical index array.

+1
source

To get the first element, try resetting the array pointer with reset (array & $ array). Then get the current value with current (). To get the Nth element, use end () to set the pointer to the last element. At this point, you can get the Nth element using current ().

+1
source

Source: https://habr.com/ru/post/889936/


All Articles