簡體   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