我怀疑在数组中进行快速搜索的更好方法是什么(我谈论的是一个特定的案例)。
假设我有一个数组L=[A,B,C](当我开始时)。当程序运行时,L可能会增长(但到最后),当我进行搜索时,一种可能的情况是L=[A,B,C,D,E]。
事实上,当我进行搜索时,我想要查找的值可能只有D和E。现在我使用find_array(elem,array),但这个函数不能"调整"为从末尾开始搜索并减少索引,我担心对于所有搜索,in_array函数会先检查所有索引较低的元素,然后才能找到我正在搜索的值。
?还有另一个搜索功能更适合我的问题??in_array函数内部如何工作?
提前感谢
我假设in_array
是从0到n-1的线性搜索。
最快的搜索将是将值存储为关键字并使用array_key_exists
。
$a['foo'] = true;
$a['bar'] = true;
if (array_key_exists('foo', $a)) ...
但如果这不是一个选项,你可以很容易地为索引数组制作自己的:
function in_array_i($needle, array $a, $i = 0);
{
$c = count($a);
for (;$i < $c; ++$i)
if ($a[$i] == $needle) return true;
return false;
}
它将从$i
开始,您可以跟踪自己,以便跳过第一个元素。
或者。。。
function in_array_i($needle, array $a, $i = 0);
{
return in_array($needle, $i ? array_slice($a, $i) : $a);
}
您可以进行基准测试,看看哪个更快。
调整之间的广泛比较测试
- in_array
- array_flicp+isset
- 数组搜索
- array_key_exists
对于数字和字符串搜索,由Kasim Kochkin发布在GitHub上,我发现以下结果
使用php 7.3.11
使用array_flicp一次和多次搜索,
-
对于单个到少量搜索,inarray和arraysearch的速度更快。
-
对于字符串搜索,flip(once)+isset在超过200次搜索时变得更快。
-
对于数字搜索,flip(once)+isset在超过10次搜索时变得更快。
字符串搜索结果(秒)
N(数组大小) | in_array | 翻转isset | array_search | array_key_exists | |
---|---|---|---|---|---|
100000 | 0.00845003 | 0.17343211 | 2.86E-6 | 0.00835395 | 5.01E-6|
10000 | 0.00854707 | 0.12469196 | 7.15E-6 | 0.00861216 | 6.2E-6 |
1000 | 0.00854087 | 0.10549212 | 6.91E-6 | 0.00846505 | 4.05E-6 |
in_array函数内部是如何工作的?
在内部,in_array()
从数组的开始到结束进行搜索。所以在你的情况下,这是缓慢的。
根据数据的性质,您可以更改搜索策略。如果您只有不重复的值,并且所有值都是字符串或整数(而不是NULL
),一个常见的技巧是array_flip()
,它工作得很快,然后通过isset()
:检查数组哈希中是否有您的值作为关键字的条目
$array = array( ... non-duplicate string and integer values ... );
$needle = 'find me!';
$lookup = array_flip($array);
$found = isset($lookup[$needle]) ? $lookup[$needle] : false;
if (false === $found) {
echo "Not found!'n";
} else {
echo "Found at {$found}!'n";
}
如果不满足这些先决条件,您可以按照konforce的建议执行。
如果你有非常多的数据,而且不仅仅是从开始或结束看,你可能想自己实现一种搜索算法,比如既不从开始也不从结束,而是包装和/或从随机位置开始以分配搜索时间。
此外,您可以在添加到数组时保持元素排序,然后使用拟合算法可以更快地搜索数组。