繁体   English   中英

PHP、in_array 和数组中的快速搜索(最后)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM