2011-06-13 101 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之间的效率之后,我们可以看到用键快速截取。