[英]PHP, in_array and fast searches (by the end) in arrays
我怀疑在数组中进行快速搜索的更好方法是什么(我说的是一个特定的案例)。
假设我有一个数组 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);
}
您可以进行基准测试以查看哪个更快。
关于您的评论,您可以这样做:
$classes = array_flip(get_declared_classes());
$check = isset($classes['%someClassName%']);
这可能会比任何价值搜索快得多。
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 的建议进行操作。
如果您有很多数据,而且不仅仅是从头或尾查看,您可能希望自己实现一个搜索算法,例如既不从头开始也不从尾开始,而是换行和/或开始在随机位置分配搜索时间。
此外,您可以在添加到数组时保持元素排序,然后可以使用拟合算法更快地搜索。
调整之间的广泛比较测试
对于数字和字符串搜索,由 Kasim Kochkin 发布在GitHub 上,我发现以下结果
使用 PHP 7.3.11
使用 array_flip 一次和多次搜索,
对于单个到几个搜索, in_array 和 array_search 更快。
对于字符串搜索,flip (once) +isset 在超过 200 次搜索时变得更快。
对于数字搜索,flip (once) +isset 在超过 10 次搜索时变得更快。
字符串搜索的结果(以秒为单位)
N(数组大小) | 数组中 | 翻动 | 伊塞特 | 数组搜索 | array_key_exists |
---|---|---|---|---|---|
1,000,000 | 0.00845003 | 0.17343211 | 2.86E-6 | 0.00835395 | 5.01E-6 |
100,000 | 0.00854707 | 0.12469196 | 7.15E-6 | 0.00861216 | 6.2E-6 |
10,000 | 0.00854087 | 0.10549212 | 6.91E-6 | 0.00846505 | 4.05E-6 |
数字搜索结果(以秒为单位),
N(数组大小) | 数组中 | 翻动 | 伊塞特 | 数组搜索 | array_key_exists |
---|---|---|---|---|---|
1,000,000 | 0.01197696 | 0.06217289 | 6.2E-6 | 0.01673698 | 4.05E-6 |
100,000 | 0.01191092 | 0.06582093 | 6.91E-6 | 0.01637983 | 4.05E-6 |
10,000 | 0.01375008 | 0.07185006 | 5.01E-6 | 0.01485705 | 4.05E-6 |
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.