PHP,in_array和快速搜索(最后)在数组中

时间:2011-06-22 07:47:06

标签: php performance search

我怀疑在数组中进行快速搜索的更好方法是什么(我在谈论具体情况)。

假设我有一个数组L = [A,B,C](当我开始时)。当程序运行时,可能L会增长(但到最后),我将进行搜索的一个可能情况是L = [A,B,C,D,E]。

事实是,当我搜索时,我想要找到的值可能只有D和E.现在我正在使用find_array(elem,array),但是这个函数不能被“调整”到搜索从最后开始并减少索引,我“害怕”对于所有搜索,函数in_array将检查所有具有较低索引的元素,然后才能找到我正在搜索的值。

¿还有另一种搜索功能更符合我的问题吗? ¿如何在in_array函数内部工作?

提前致谢

4 个答案:

答案 0 :(得分:8)

我假设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);
}

你可以通过基准来看看哪个更快。

答案 1 :(得分:3)

关于你的评论,你可以这样做:

$classes = array_flip(get_declared_classes());
$check = isset($classes['%someClassName%']);

这可能会比任何价值搜索快得多。

答案 2 :(得分:1)

  

in_array函数内部如何工作?

Internally 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 建议的内容。

如果您拥有非常多的数据并且不仅仅是从开头或结尾看,您可能希望自己实现一种搜索算法,例如既不从头开始也不是结束,而是包装和/或从随机位置开始分发搜索时间。

此外,您可以在添加到数组时对元素进行排序,然后使用拟合算法可以更快地搜索元素。

答案 3 :(得分:0)

调整之间的广泛比较测试

对于数字和字符串搜索,Kasim Kochkin发表于GitHub,发现以下结果

使用php 7.3.11

一次使用array_flip进行多次搜索,

  • 对于单次或几次搜索,in_array和array_search更快。

  • 对于字符串搜索,翻转(一次)+ isset变得比200次搜索更快。

  • 对于数字搜索,翻转(一次)+ isset变得比10次搜索快。

字符串搜索结果

N = 1000000(百万) in_array:0.00845003 翻转:0.17343211 isset:2.86E-6 array_search:0.00835395 array_key_exists:5.01E-6

N = 100000 in_array:0.00854707 翻转:0.12469196 isset:7.15E-6 array_search:0.00861216 array_key_exists:6.2E-6

N = 10000 in_array:0.00854087 翻转:0.10549212 isset:6.91E-6 array_search:0.00846505 array_key_exists:4.05E-6

数字搜索结果

N = 1000000 in_array:0.01197696 翻转:0.06217289 isset:6.2E-6 array_search:0.01673698 array_key_exists:4.05E-6

N = 100000 in_array:0.01191092 翻转:0.06582093 isset:6.91E-6 array_search:0.01637983 array_key_exists:4.05E-6

N = 10000 in_array:0.01375008 翻转:0.07185006 isset:5.01E-6 array_search:0.01485705 array_key_exists:4.05E-6