php数组_intersect()效率

php数组_intersect()效率,php,Php,考虑下面的脚本。只有三个值的两个数组。当我使用array_intersect()比较这两个数组时。结果很快 <?php $arrayOne = array('3', '4', '5'); $arrayTwo = array('4', '5', '6'); $intersect = array_intersect($arrayOne, $arrayTwo); print_r($intersect ); ?> 我的问题是数组_intersect()的效率是多少。是否比

考虑下面的脚本。只有三个值的两个数组。当我使用array_intersect()比较这两个数组时。结果很快

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

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

print_r($intersect );

?>

我的问题是数组_intersect()的效率是多少。是否比较两个都有1000个值的数组。会产生更好的结果。。。。。我们需要使用一些散列函数来处理快速查找公共值的问题,这将是有效的???。。我需要你的建议


我正在做一个应用程序。如果一个人使用facebook登录来登录。那么该应用程序将获得他的好友列表,并查找是否有以前在我的应用程序中评论过的好友,并将其显示给他。大约一个朋友在facebook上可能有200到300个朋友,db有1000多条记录。我需要找到有效的方法,通过在第二个数组中构造一组搜索值,可以实现交集,并且在一个集合中查找的速度可以非常快,平均需要恒定的时间。因此,整个算法的运行时间可以是
O(n)

或者,可以对第二个数组进行排序(在
O(n log n)
中)。由于在排序数组中查找时在
O(logn)
中有一个运行时,因此整个算法应该在
O(nlogn)
中有一个运行时

根据我刚刚运行的一个(简短的、不科学的)测试,php的
数组\u intersect
似乎就是这样:


我曾经测试过它。正如您所看到的,对于小到1000的输入大小,您不必担心。

根据上面的说明,我建议您实现缓存机制。这样,您就可以更好地加载数据库并加快应用程序的速度。我还建议您分析阵列_与不断增加的数据量相交的速度,以了解性能如何扩展。您可以通过简单地在系统时间内包装调用并计算差异来实现这一点。但是我建议你使用一个真正的分析器来获得好的数据

在并行比较数组的值之前对数组进行排序(请参阅中使用的
zendqsort
)。仅此一步,每个数组就需要O(n·logn)。那么实际的交叉点只需要线性时间

根据数组中的值,可以在线性时间内实现此交集,而无需排序,例如:

$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);

我实现了比较数组相交和数组相交键的简单代码

$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>';

通过比较array\u intersect和array\u intersect\u key的效率,我们可以看到使用key的拦截速度要快得多。

我找到的最快解决方案是:

function arrayIntersect($arrayOne, $arrayTwo) {
        $index = array_flip($arrayOne);
        $second = array_flip($arrayTwo);

        $x = array_intersect_key($index, $second);

        return array_flip($x);
}
我所做的测试如下所示:

function intersect($arrayOne, $arrayTwo)
{
    $index = array_flip($arrayOne);
    foreach ($arrayTwo as $value) {
        if (isset($index[$value])) unset($index[$value]);
    }
    foreach ($index as $value => $key) {
        unset($arrayOne[$key]);
    }

    return $arrayOne;
}

function intersect2($arrayOne, $arrayTwo)
{
    $index = array_flip($arrayOne);
    $second = array_flip($arrayTwo);

    $x = array_intersect_key($index, $second);

    return array_flip($x);

}

for($i =0; $i < 1000000; $i++) {
    $one[] = rand(0,1000000);
    $two[] = rand(0,100000);
    $two[] = rand(0,10000);
}

$one = array_unique($one);
$two = array_unique($two);

$time_start = microtime(true);
$res = intersect($one, $two);
$time = microtime(true) - $time_start;

echo "Sort time $time seconds 'intersect' \n";


$time_start = microtime(true);
$res2 = array_intersect($one, $two);
$time = microtime(true) - $time_start;

echo "Sort time $time seconds 'array_intersect' \n";


$time_start = microtime(true);
$res3 = intersect2($one, $two);
$time = microtime(true) - $time_start;

echo "Sort time $time seconds 'intersect2' \n";

@向他人学习:您是否在具有1000+个值的数组上尝试过相同的方法?为什么不亲自了解一下呢?做一个基准测试。一般来说,它是否有效并不重要,除非您分析了应用程序并发现对array_intersect的调用显著降低了应用程序的速度。多少是重要的是你的要求。@codingfreak不,我没有尝试过。我正在做一个应用程序。如果一个人使用facebook登录来登录。那么该应用程序将获得他的好友列表,并查找是否有以前在我的应用程序中评论过的好友,并将其显示给他。大约一个朋友在facebook上可能有200到300个朋友,db有1000多条记录。我需要找到有效的方法,我如何才能做到这一点……@Gordan对于任何解决方案。。。。。我正在做一个应用程序。如果一个人使用facebook登录来登录。那么该应用程序将获得他的好友列表,并查找是否有以前在我的应用程序中评论过的好友,并将其显示给他。大约一个朋友在facebook上可能有200到300个朋友,db有1000多条记录。我需要找到有效的方法我怎么能做到……但是你怎么能确定你会遇到只有200到300个朋友的人呢?我在facebook上看到的个人资料有超过5K个以上的朋友。@learnfromothers:profiler是一种帮助您测量应用程序性能的应用程序。以Xdebug为例:或者如果你使用Zend Studio,他们有一个内置的:@inquam ya谢谢。我可以使用一些散列函数来将值存储在db中,这样可以稍微限制搜索。这是一种正确的方法吗?@learnfromothers:访问数据的最佳方式取决于多种因素。数据的布局、读取和写入的频率等。但是,有了分析器,您可以快速看到不同的方法和特定的更改如何影响您的性能。@inquam再次感谢。。。。但是,你知道在当今以及facebook等主要网站上,高效存储和检索数据的最佳方法吗?@laernfromothers:我知道facebook在很大程度上依赖于数据缓存。我认为他们使用的是memcache的修改版。这将数据存储在内存中,与一直从DB获取数据相比,速度非常快。另外,我认为他们预先计算了关键信息,这样你就不必每次都这样做了。说出你的朋友名单。您可以编译一次并将其存储在缓存中。然后你可以在每次需要的时候从那里取回它。只有当你添加或删除一个朋友时,它才会被重建。@phinag ya没错。。。。对此,任何解决方案。。。。。我正在做一个应用程序。如果一个人使用facebook登录来登录。那么该应用程序将获得他的好友列表,并查找是否有以前在我的应用程序中评论过的好友,并将其显示给他。大约一个朋友在facebook上可能有200到300个朋友,db有1000多条记录。我需要找到有效的解决方法。@learnfromothers
array\u intersect
在不到1000个元素的情况下不会成为性能问题。谢谢。为了你的效果。非常满意你的回答。。。。再次感谢………@phihag如果你还记得,t是什么
function intersect($arrayOne, $arrayTwo)
{
    $index = array_flip($arrayOne);
    foreach ($arrayTwo as $value) {
        if (isset($index[$value])) unset($index[$value]);
    }
    foreach ($index as $value => $key) {
        unset($arrayOne[$key]);
    }

    return $arrayOne;
}

function intersect2($arrayOne, $arrayTwo)
{
    $index = array_flip($arrayOne);
    $second = array_flip($arrayTwo);

    $x = array_intersect_key($index, $second);

    return array_flip($x);

}

for($i =0; $i < 1000000; $i++) {
    $one[] = rand(0,1000000);
    $two[] = rand(0,100000);
    $two[] = rand(0,10000);
}

$one = array_unique($one);
$two = array_unique($two);

$time_start = microtime(true);
$res = intersect($one, $two);
$time = microtime(true) - $time_start;

echo "Sort time $time seconds 'intersect' \n";


$time_start = microtime(true);
$res2 = array_intersect($one, $two);
$time = microtime(true) - $time_start;

echo "Sort time $time seconds 'array_intersect' \n";


$time_start = microtime(true);
$res3 = intersect2($one, $two);
$time = microtime(true) - $time_start;

echo "Sort time $time seconds 'intersect2' \n";
Sort time 0.77021193504333 seconds 'intersect' 
Sort time 6.9765028953552 seconds 'array_intersect' 
Sort time 0.4631941318512 seconds 'intersect2'