简体   繁体   English

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

[英]PHP, in_array and fast searches (by the end) in arrays

I have a doubt about what's the better way to make a fast search in arrays (I'm talking about an specific case).我怀疑在数组中进行快速搜索的更好方法是什么(我说的是一个特定的案例)。

Supose that I have an array L = [A, B, C] (when I start).假设我有一个数组 L = [A, B, C] (当我开始时)。 While the program is running, may be L will grow (but by the end), one possible case when I'll do the search is that L = [A, B, C, D, E].当程序运行时,L 可能会增长(但到最后),我进行搜索的一种可能情况是 L = [A, B, C, D, E]。

The fact is that when I'm searching, the values that I want find could be only D and E. Now I'm using find_array(elem, array), but this function can't be "tweaked" to search starting at the end and decreasing the index, and I'm "afraid" that for all the searches the function in_array will examine all the elements with lower indexes before will find the value that I'm searching.事实是,当我搜索时,我想要查找的值可能只有 D 和 E。现在我使用的是 find_array(elem, array),但是不能“调整”此函数以从结束并减少索引,我“害怕”对于所有搜索,函数 in_array 将检查所有具有较低索引的元素,然后才能找到我正在搜索的值。

¿There is another search function wich fits better to my problem? ¿还有另一个搜索功能更适合我的问题吗? ¿How works internally the in_array function? ¿in_array 函数在内部如何工作?

Thanks in advance提前致谢

I assume that in_array is a linear search from 0 to n-1.我假设in_array是从 0 到 n-1 的线性搜索。

The fastest search will be to store the values as the keys and use array_key_exists .最快的搜索是将值存储为键并使用array_key_exists

$a['foo'] = true;
$a['bar'] = true;

if (array_key_exists('foo', $a)) ...

But if that's not an option, you can make your own for indexed arrays quite easily:但是,如果这不是一个选项,您可以很容易地为索引数组创建自己的:

function in_array_i($needle, array $a, $i = 0);
{
  $c = count($a);
  for (;$i < $c; ++$i)
    if ($a[$i] == $needle) return true;
  return false;
}

It will start at $i , which you can keep track of yourself in order to skip the first elements.它将从$i开始,您可以跟踪自己以跳过第一个元素。

Or alternatively...或者替代...

function in_array_i($needle, array $a, $i = 0);
{
  return in_array($needle, $i ? array_slice($a, $i) : $a);
}

You can benchmark to see which is faster.您可以进行基准测试以查看哪个更快。

With regards to your comment, you could do: 关于您的评论,您可以这样做:

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

Which will probably be a lot faster then any value-searching. 这可能会比任何价值搜索快得多。

How works internally the in_array function? in_array 函数内部如何工作?

Internally the in_array() searches from the beginning to the end of the array. in_array()内部从数组的开头到结尾搜索。 So in your case this is slow.所以在你的情况下,这很慢。

Depending of the nature of your data you can change the search strategy.根据数据的性质,您可以更改搜索策略。 If you only have non-duplicate values and all values are either string or integer (not NULL ), a common trick is to array_flip() the array which works pretty fast and then check if there is an entry for your value as key in the array hash via isset() :如果您只有非重复值并且所有值都是字符串或整数(不是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";
  }

If these pre-conditions are not met, you can do that what konforce suggested.如果不满足这些先决条件,您可以按照konforce 的建议进行操作。

If you have really much data and it's not only that you're looking at either from the beginning or end, you might want to implement one search algorithm on your own, like neither starting from the beginning nor end, but wrapping and/or starting at a random position to distribute the search time.如果您有很多数据,而且不仅仅是从头或尾查看,您可能希望自己实现一个搜索算法,例如既不从头开始也不从尾开始,而是换行和/或开始在随机位置分配搜索时间。

Additionally you can keep elements sorted while adding to the array probably which can then be searched much faster with a fitting algorithm.此外,您可以在添加到数组时保持元素排序,然后可以使用拟合算法更快地搜索。

Tweaking an extensive comparative test between调整之间的广泛比较测试

for numerical and string searches, by Kasim Kochkin posted on GitHub , I find the following results对于数字和字符串搜索,由 Kasim Kochkin 发布在GitHub 上,我发现以下结果

using php 7.3.11使用 PHP 7.3.11

using array_flip once and multiple searches,使用 array_flip 一次和多次搜索,

  • for single to few searches, in_array and array_search are faster.对于单个到几个搜索, in_array 和 array_search 更快。

  • for string searches, flip (once) + isset becomes faster above 200 searches.对于字符串搜索,flip (once) +isset 在超过 200 次搜索时变得更快。

  • for numerical searches, flip (once) + isset becomes faster above 10 searches.对于数字搜索,flip (once) +isset 在超过 10 次搜索时变得更快。

results for String search (in seconds)字符串搜索的结果(以秒为单位)

N (array size) N(数组大小) in_array数组中 flip翻动 isset伊塞特 array_search数组搜索 array_key_exists array_key_exists
1,000,000 1,000,000 0.00845003 0.00845003 0.17343211 0.17343211 2.86E-6 2.86E-6 0.00835395 0.00835395 5.01E-6 5.01E-6
100,000 100,000 0.00854707 0.00854707 0.12469196 0.12469196 7.15E-6 7.15E-6 0.00861216 0.00861216 6.2E-6 6.2E-6
10,000 10,000 0.00854087 0.00854087 0.10549212 0.10549212 6.91E-6 6.91E-6 0.00846505 0.00846505 4.05E-6 4.05E-6

Numerical search results (in seconds),数字搜索结果(以秒为单位),

N (array size) N(数组大小) in_array数组中 flip翻动 isset伊塞特 array_search数组搜索 array_key_exists array_key_exists
1,000,000 1,000,000 0.01197696 0.01197696 0.06217289 0.06217289 6.2E-6 6.2E-6 0.01673698 0.01673698 4.05E-6 4.05E-6
100,000 100,000 0.01191092 0.01191092 0.06582093 0.06582093 6.91E-6 6.91E-6 0.01637983 0.01637983 4.05E-6 4.05E-6
10,000 10,000 0.01375008 0.01375008 0.07185006 0.07185006 5.01E-6 5.01E-6 0.01485705 0.01485705 4.05E-6 4.05E-6

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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