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

PHP、in_数组和数组中的快速搜索(最后),php,performance,search,Php,Performance,Search,我怀疑在数组中进行快速搜索的更好方法是什么(我谈论的是一个具体案例) 假设我有一个数组L=[A,B,C](当我开始时)。当程序运行时,可能L会增长(但到最后),我进行搜索的一种可能情况是L=[A,B,C,D,E] 事实上,当我搜索时,我想要查找的值只能是D和E。现在我使用find_数组(elem,array),但是这个函数不能“调整”从末尾开始搜索并减少索引,我很“害怕”对于所有搜索,_数组中的函数将检查之前具有较低索引的所有元素,从而找到我正在搜索的值 ?还有另一个搜索功能更适合我的问题吗??

我怀疑在数组中进行快速搜索的更好方法是什么(我谈论的是一个具体案例)

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

事实上,当我搜索时,我想要查找的值只能是D和E。现在我使用find_数组(elem,array),但是这个函数不能“调整”从末尾开始搜索并减少索引,我很“害怕”对于所有搜索,_数组中的函数将检查之前具有较低索引的所有元素,从而找到我正在搜索的值

?还有另一个搜索功能更适合我的问题吗??in_数组函数内部如何工作


提前感谢

我假设数组中的
是从0到n-1的线性搜索

最快的搜索将是将值存储为键,并使用
array\u key\u 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;
}
您可以进行基准测试以查看哪个更快

in_数组函数内部如何工作

_array()中的
从数组的开始到结束进行搜索。所以在你的情况下,这是缓慢的

根据数据的性质,您可以更改搜索策略。如果您只有非重复值,并且所有值都是字符串或整数(而不是
NULL
),一个常见的技巧是使用运行非常快的数组,然后通过
isset()
检查数组散列中是否有值作为键的条目:

如果不满足这些先决条件,您可以按照konforce的建议执行

如果您拥有大量数据,并且不仅是从开始或结束查看,您可能希望自己实现一个搜索算法,例如既不从开始也不从结束,而是包装和/或从随机位置开始以分配搜索时间


此外,您可以在添加到数组时保持元素的排序,然后使用拟合算法可以更快地搜索这些元素。

调整这些元素之间的广泛比较测试

  • +
对于Kasim Kochkin发布的数字和字符串搜索,我发现以下结果

使用PHP7.3.11

使用数组翻转一次和多次搜索

  • 对于单个或少数搜索,in_数组和array_搜索速度更快

  • 对于字符串搜索,翻转(一次)+isset在超过200次搜索时变得更快

  • 对于数值搜索,翻转(一次)+isset在10次搜索以上时会变得更快

字符串搜索结果(秒)

N(数组大小) in_数组 轻弹 伊塞特 数组搜索 数组\密钥\存在 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
旁注:如果事先知道只搜索新值?难道不可能将这些新值存储在一个单独的数组中,该数组将更小,因此搜索速度更快吗?(如果kenforces answer不是您的选项)我正在使用get_declared_classes()函数,我必须发现是否加载了特定的类……php手册没有提到函数find_array()。所以我想知道你是想要找到的元素的密钥,还是只想知道该元素是否存在。我只想验证它是否存在。。。但也许我所做的不是正确的方式。我将尝试使用class_exists()函数。@JordanArseno,是的
isset()
array_key_exists()
快,但对于
null
值,它确实返回
false
。(在这种情况下,这并不重要。)也就是说,它们本质上都是常数时间,而_array()
中的
是O(n),当到达大型数组的末尾时,性能会明显下降。因此,当
null
不是问题时,我更喜欢使用
isset()
,但主要的收获应该是
in_array()
绝对是强制唯一性的错误方法。你的帖子在@Aurovrata看起来非常有用,但目前很难阅读。你能用一个表格来格式化它吗?它能以一种更易读的方式显示基准吗?当然,我会设法找一些时间来改进它。这里有一个降价表格生成器@Aurovrata:wow,这真的很方便。我将使用此表格格式更新我的答案
function in_array_i($needle, array $a, $i = 0);
{
  return in_array($needle, $i ? array_slice($a, $i) : $a);
}
  $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";
  }