2011-06-13 14 views
6

considere la siguiente secuencia de comandos. dos matrices con solo tres valores. Cuando comparo estas dos matrices usando array_intersect(). el resultado es rápidophp array_intersect() eficiencia

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

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

print_r($intersect); 

?> 

mi pregunta es cuál es la eficacia de array_intersect(). ya sea si comparamos dos matrices que tienen 1000 valores cada una. produciría un mejor resultado ..... r tenemos que usar alguna función hash para tratar de encontrar valores comunes rápidamente lo que será efectivo ??? .. necesito tu sugerencia para esto ...

estoy haciendo una aplicación.si una persona viene e inicia sesión utilizando Facebook login.then la aplicación obtendrá su lista de amigos y encontrar si algún amigo como se comentó en mi aplicación antes y mostrarle a él. aproximadamente unos amigos pueden tener entre 200 y 300 amigos en Facebook y DB tiene más de 1000 registros. Necesito encontrar eso de manera eficiente, ¿cómo puedo hacer eso .......

+0

@learnfromothers: ¿has probado lo mismo en matrices con más de 1000 valores? –

+2

¿por qué no lo averiguas? hacer un punto de referencia. en general, no importa si es eficiente o no, a menos que haya perfilado su aplicación y haya encontrado que las llamadas a array_intersect están ralentizando significativamente su aplicación. Cuánto es significativo depende de sus requisitos. – Gordon

+0

@Coding Freak no, no lo he intentado. Estoy haciendo una aplicación. Si una persona entra y inicia sesión con Facebook, inicie sesión. Entonces, la aplicación obtendrá su lista de amigos y encontrará si algún amigo como se comentó anteriormente en mi aplicación y se lo mostrará. aproximadamente unos amigos pueden tener entre 200 y 300 amigos en Facebook y DB tiene más de 1000 registros. necesito encontrar eso de manera eficiente, ¿cómo puedo hacer eso ....... – learnfromothers

Respuesta

19

La intersección se puede implementar mediante la construcción de un conjunto de los valores buscados en la segunda matriz, y buscar en un conjunto se puede hacer tan rápido que se necesita un tiempo esencialmente constante en promedio. Por lo tanto, el tiempo de ejecución de todo el algoritmo puede estar en O(n).

Alternativamente, se puede ordenar la segunda matriz (en O(n log n)). Como la búsqueda en una matriz ordenada tiene un tiempo de ejecución en O(log n), todo el algoritmo debería tener un tiempo de ejecución en O(n log n).

De acuerdo con una prueba (corto, no científica) Acabo de funcionar, esto parece ser el caso de php de array_intersect:

Performance of array_intersect

Here's the code he usado para probarlo. Como puede ver, para un tamaño de entrada tan pequeño como 1000, no necesita preocuparse.

+0

@phinag eso es correcto ... para esto cualquier solución ..... estoy haciendo una aplicación. Si una persona viene y inicia sesión usando facebook login.then la aplicación obtendrá su lista de amigos y encontrará si algún amigo ha comentado en mi aplicación anterior y mostrarle a él. aproximadamente unos amigos pueden tener entre 200 y 300 amigos en Facebook y DB tiene más de 1000 registros. Necesito encontrarlo de manera eficiente, ¿cómo puedo hacer eso? – learnfromothers

+0

@learnfromothers 'array_intersect' no será el problema de rendimiento para menos de mil elementos. – phihag

+0

gracias. por tu efecto muy estadísticamente con su respuesta ... gracias de nuevo ......... – learnfromothers

2

De lo que dice más arriba, le recomendaría implementar un mecanismo de almacenamiento en caché. De esa forma, cargaría el DB y aceleraría su aplicación. También te recomendaría que perfilaras la velocidad de array_intersect con una mayor cantidad de datos para ver cómo funciona la escala. Puede hacer esto simplemente envolviendo la llamada en llamadas para la hora del sistema y calcular la diferencia. Pero le recomendaría que use un generador de perfiles real para obtener buenos datos.

+0

@inquam profiler significa ?????? – learnfromothers

+1

@learnfromothers: un generador de perfiles es una aplicación que le ayuda a medir el rendimiento de su aplicación. Mire Xdebug por ejemplo: http://www.xdebug.org/docs/profiler o si usa Zend Studio tienen uno integrado: http://files.zend.com/help/Beta/Zend_Studio_8_0/working_with_the_profiler. htm – inquam

+0

@inquam ya gracias. ¿Puedo usar alguna función hash para almacenar los valores en db para que la búsqueda se pueda limitar un poco? ¿Es ese un enfoque correcto? – learnfromothers

14

array_intersect ordena las matrices antes de comparar sus valores en paralelo (consulte el uso de zend_qsort en el source file array.c). Solo esto toma O (n · log n) para cada matriz. Entonces la intersección real solo toma tiempo lineal.

En función de los valores de las matrices, se podría aplicar esta intersección en el tiempo lineal y sin la clasificación, por ejemplo:

$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

gracias gumbo por tu respuesta ......... – learnfromothers

0

que la aplicación de este código simple de comparar array_intersect y 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>'; 

el resultado ....

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

I n esta comparación de la eficiencia entre array_intersect y array_intersect_key, podemos ver que la interceptación con claves es mucho más rápida.

Cuestiones relacionadas