2011-06-13 102 views
6

考慮下面的腳本。兩個數組只有三個值。當我使用array_intersect()比較這兩個數組時。結果很快。php array_intersect()效率

<?php 
$arrayOne = array('3', '4', '5'); 
$arrayTwo = array('4', '5', '6'); 

$intersect = array_intersect($arrayOne, $arrayTwo); 

print_r($intersect); 

?> 

我的問題是什麼是array_intersect()的效率。無論我們是否比較兩個數組都有1000個值。會產生更好的結果..... r我們需要使用一些哈希函數來處理快速找到共同的價值,這將是有效的..我需要你對此的建議...

我在做一個application.if一個人來到並使用facebook登錄登錄。然後,應用程序將獲得他的朋友列表,並查找是否有朋友在我的應用程序中評論過,並向他展示。大概一個朋友可能在facebook上有200到300個朋友,而db有超過1000個記錄。我需要高效地找到我該怎麼做.......

+0

@learnfromothers:你有沒有試過與1000 +值的數組相同的東西? – 2011-06-13 10:33:19

+2

爲什麼不找出你自己?做一個基準。一般來說,不管它是否有效,除非你對你的應用程序進行了分析,並發現對array_intersect的調用會顯着減慢你的應用程序。有多重要取決於您的要求。 – Gordon 2011-06-13 10:37:44

+0

@編碼怪胎不,我還沒有嘗試過。我正在做一個應用程序。如果有人來登錄並使用Facebook登錄,那麼應用程序將獲得他的朋友列表,並查找是否有朋友在我的應用程序中評論過,並向他展示。大概一個朋友可能在facebook上有200到300個朋友,而db有超過1000個記錄。我需要找到有效的,我該怎麼做....... – learnfromothers 2011-06-13 10:37:52

回答

19

相交可以通過在第二個數組中構建一組搜索值來實現,並且查找一組可以做得如此之快它平均需要基本不變的時間。因此,整個算法的運行時間可以在O(n)

或者,可以對第二個數組進行排序(在O(n log n)中)。由於在排序的數組中查找的運行時間爲O(log n),因此整個算法的運行時間應在O(n log n)之間。

根據(短,不科學)測試我只是跑,這似乎是PHP的array_intersect的情況:

Performance of array_intersect

Here's the code我用來測試它。正如您所看到的,對於小至1000的輸入大小,您無需擔心。

+0

@phinag ya多數民衆贊成正確....對於任何解決方案.....我正在做一個應用程序。如果一個人來和登錄使用Facebook登錄。然後應用程序會得到他的朋友列表,並找到是否有朋友評論在我的應用程序之前,並顯示給他。大概一個朋友可能在facebook上有200到300個朋友,而db有超過1000個記錄。我需要高效率地找到我該怎麼做。 – learnfromothers 2011-06-13 10:54:55

+0

@learnfromothers'array_intersect'不會成爲少於一千個元素的性能問題。 – phihag 2011-06-13 11:00:13

+0

謝謝。爲了你的效果。非常感謝您的回答....再次感謝......... – learnfromothers 2011-06-13 11:01:32

2

從你上面的狀態,我會建議你實現一個緩存機制。這樣你就可以加載數據庫並加快你的應用程序。我還建議你用數據量增加的數據來分析array_intersect的速度,以查看性能如何擴展。您可以通過簡單地將呼叫打包爲系統時間呼叫來計算差異。但我會建議你使用真實的分析器來獲取好的數據。

+0

@inquam分析器意味着?????? – learnfromothers 2011-06-13 10:48:07

+1

@learnfromothers:分析器是一個可幫助您確定應用程序性能的應用程序。以Xdebug爲例:http://www.xdebug.org/docs/profiler或者如果您使用Zend Studio,他們有一個內置的:http://files.zend.com/help/Beta/Zend_Studio_8_0/working_with_the_profiler。 htm – inquam 2011-06-13 10:49:40

+0

@inquam雅感謝。我可以使用一些散列函數來將值存儲在分貝中,以便搜索可以受到一定限制。這是一個正確的做法嗎? – learnfromothers 2011-06-13 10:52:48

14

array_intersect在並行比較它們的值之前對數組進行排序(請參閱在source file array.c中使用zend_qsort)。這僅需要每個陣列的O(n·log n)。那麼實際的交叉點只需要線性時間。

根據您的陣列中的值,你可以實現線性時間這個路口沒有排序,例如:

$index = array_flip($arrayOne); 
foreach ($arrayTwo as $value) { 
    if (isset($index[$value])) unset($index[$value]); 
} 
foreach ($index as $value => $key) { 
    unset($arrayOne[$key]); 
} 
var_dump($arrayOne); 
+0

感謝你的回答........ – learnfromothers 2011-06-13 11:02:18

0

我實現比較array_intersect和array_intersect_key的這個簡單的代碼,

$array = array(); 
    for($i=0; $i<130000; $i++) 
     $array[$i] = $i; 
    for($i=200000; $i<230000; $i++) 
     $array[$i] = $i; 
    for($i=300000; $i<340000; $i++) 
     $array[$i] = $i; 

    $array2 = array(); 
    for($i=100000; $i<110000; $i++) 
     $array2[$i] = $i; 
    for($i=90000; $i<100000; $i++) 
     $array2[$i] = $i; 
    for($i=110000; $i<290000; $i++) 
     $array2[$i] = $i; 

    echo 'Intersect to arrays -> array1[' . count($array) . '] : array2[' . count($array2) . '] ' . '<br>'; 
    echo date('Y-m-d H:i:s') . '<br>'; 
    $time = time(); 
    $array_r2 = array_intersect_key($array,$array2); 
    echo 'Intercept key: ' . (time()-$time) . ' segs<br>'; 
    $time = time(); 
    $array_r = array_intersect($array,$array2); 
    echo 'Intercept: ' . (time()-$time) . ' segs<br>'; 

結果....

Intersect to arrays -> array1[200000] : array2[200000] 
2014-10-30 08:52:52 
Intercept key: 0 segs 
Intercept: 4 segs 

我在比較array_intersect和array_intersect_key之間的效率之後,我們可以看到用鍵快速截取。