我有一个很大的哈希表(带有字符串索引的数组),并且正在寻找一个快速从中挑选第一个(理想情况下也是第N个)元素的函数。 array_shift()
和reset()
对我的需求来说太慢了。
更新:我也不是在寻找基于参考的解决方案,该函数应该接受get_first(some_func_returning_array())
ANSWER array_slice方法(kudos Gumbo)似乎是胜利者。完整的基准代码
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);
结果:
dummy = 0.393
slice = 0.433
values = 0.824
foreach = 0.929
reset = 0.935
array_shift = 0.954
keys = 1.371
答案 0 :(得分:7)
使用array_slice
获取 n 项的数组和array_pop
以最终得到它:
$nthItem = array_pop(array_slice($arr, $n, 1));
答案 1 :(得分:4)
您的基准可能存在缺陷,因为:
$fn = function ($a) {
return array_shift($a);
};
timeit('array_shift', $fn);
array_shift = 1.242(5432)
和
timeit('array_shift', array_shift);
array_shift = 0.026(4433)
但也
$fn = function ($a) { }
timeit('empty lambda', $fn);
空lambda = 0.501(0)
话虽如此,另一种可能的解决方案是:
$v = array_values($a);
return $v[ $index ];
示例代码:
$t = microtime(1);
$v = array_values($a); // cached
while($loops--) {
$b = $v[$loops];
}
array_values = 0.002(5432)
答案 2 :(得分:2)
对于第一个/最后一个元素,我认为你不能比reset()
/ end()
更快。
关于第N个元素,我想不出比这更好的东西:
function (&$hashmap, $n) {
$keys = array_keys($hashmap);
return $hashmap[$keys[$n]];
}
当然,对于性能,可以调整为具有预缓存的$keys
数组(如果hashmap不经常更改)。在这种情况下,甚至第0个元素检索可能比使用reset()
答案 3 :(得分:1)
获得第一个:
function array_first(array $array) {
foreach ($array as $value) return $value;
return false;
}
虽然我没有测试这个速度,但您可以尝试使用array_values()
将数组转换为数字索引数组。
答案 4 :(得分:1)
要获取第一个元素,请尝试使用reset(array&amp; $ array)重置数组的指针。 然后用current()获取当前值。要获取第N个元素,请使用end(),将指针设置为最后一个项目。此时,您应该能够使用current()获取第N个项目。