Debido a las maravillas de la predicción de bifurcación, una búsqueda binaria puede ser más lenta que una búsqueda lineal a través de una matriz de enteros. En un procesador de escritorio típico, ¿qué tan grande tiene que llegar ese conjunto antes de que sea mejor utilizar una búsqueda binaria? Supongamos que la estructura se usará para muchas búsquedas.¿En qué n la búsqueda binaria se vuelve más rápida que la búsqueda lineal en una CPU moderna?
Respuesta
He intentado un poco de benchmarking de C++ y estoy sorprendido: la búsqueda lineal parece prevalecer hasta varias docenas de artículos, y no he encontrado un caso en que la búsqueda binaria sea mejor para esos tamaños. ¿Quizás el STL de gcc no está bien ajustado? Pero entonces - ¿qué se puede utilizar para implementar cualquiera tipo de búsqueda -) Así que aquí está mi código, por lo que todo el mundo puede ver si he hecho algo tonto que puedan falsear la sincronización groseramente ...:?
#include <vector>
#include <algorithm>
#include <iostream>
#include <stdlib.h>
int data[] = {98, 50, 54, 43, 39, 91, 17, 85, 42, 84, 23, 7, 70, 72, 74, 65, 66, 47, 20, 27, 61, 62, 22, 75, 24, 6, 2, 68, 45, 77, 82, 29, 59, 97, 95, 94, 40, 80, 86, 9, 78, 69, 15, 51, 14, 36, 76, 18, 48, 73, 79, 25, 11, 38, 71, 1, 57, 3, 26, 37, 19, 67, 35, 87, 60, 34, 5, 88, 52, 96, 31, 30, 81, 4, 92, 21, 33, 44, 63, 83, 56, 0, 12, 8, 93, 49, 41, 58, 89, 10, 28, 55, 46, 13, 64, 53, 32, 16, 90
};
int tosearch[] = {53, 5, 40, 71, 37, 14, 52, 28, 25, 11, 23, 13, 70, 81, 77, 10, 17, 26, 56, 15, 94, 42, 18, 39, 50, 78, 93, 19, 87, 43, 63, 67, 79, 4, 64, 6, 38, 45, 91, 86, 20, 30, 58, 68, 33, 12, 97, 95, 9, 89, 32, 72, 74, 1, 2, 34, 62, 57, 29, 21, 49, 69, 0, 31, 3, 27, 60, 59, 24, 41, 80, 7, 51, 8, 47, 54, 90, 36, 76, 22, 44, 84, 48, 73, 65, 96, 83, 66, 61, 16, 88, 92, 98, 85, 75, 82, 55, 35, 46
};
bool binsearch(int i, std::vector<int>::const_iterator begin,
std::vector<int>::const_iterator end) {
return std::binary_search(begin, end, i);
}
bool linsearch(int i, std::vector<int>::const_iterator begin,
std::vector<int>::const_iterator end) {
return std::find(begin, end, i) != end;
}
int main(int argc, char *argv[])
{
int n = 6;
if (argc < 2) {
std::cerr << "need at least 1 arg (l or b!)" << std::endl;
return 1;
}
char algo = argv[1][0];
if (algo != 'b' && algo != 'l') {
std::cerr << "algo must be l or b, not '" << algo << "'" << std::endl;
return 1;
}
if (argc > 2) {
n = atoi(argv[2]);
}
std::vector<int> vv;
for (int i=0; i<n; ++i) {
if(data[i]==-1) break;
vv.push_back(data[i]);
}
if (algo=='b') {
std::sort(vv.begin(), vv.end());
}
bool (*search)(int i, std::vector<int>::const_iterator begin,
std::vector<int>::const_iterator end);
if (algo=='b') search = binsearch;
else search = linsearch;
int nf = 0;
int ns = 0;
for(int k=0; k<10000; ++k) {
for (int j=0; tosearch[j] >= 0; ++j) {
++ns;
if (search(tosearch[j], vv.begin(), vv.end()))
++nf;
}
}
std::cout << nf <<'/'<< ns << std::endl;
return 0;
}
y mi un par de mis tiempos en un dúo de la base:
AmAir:stko aleax$ time ./a.out b 93
1910000/2030000
real 0m0.230s
user 0m0.224s
sys 0m0.005s
AmAir:stko aleax$ time ./a.out l 93
1910000/2030000
real 0m0.169s
user 0m0.164s
sys 0m0.005s
Son muy repetible, de todos modos ...
OP dice: Alex, editado su programa sólo tiene que rellenar la matriz con 1 .. n, no ejecuta std :: sort, y realiza aproximadamente 10 millones de búsquedas (división de enteros mod). La búsqueda binaria comienza a alejarse de la búsqueda lineal en n = 150 en un Pentium 4. Lo siento por los colores del gráfico.
Estás compilando con-O3 ¿verdad? – GManNickG
Esto es -O - -O3 hace la búsqueda lineal un poco peor, 178 mseg o más, y la búsqueda binaria es un poco mejor, 222 mseg o más. –
No muchas, pero es difícil de decir exactamente sin compararla.
Personalmente prefiero la búsqueda binaria, porque en dos años, cuando otra persona ha cuadruplicado el tamaño de su pequeña matriz, no ha perdido mucho rendimiento. A menos que supiera muy específicamente que es un cuello de botella en este momento y que necesitaba que fuera lo más rápido posible, por supuesto.
Habiendo dicho eso, recuerde que también hay tablas hash; podrías hacer una pregunta similar sobre ellos vs. búsqueda binaria.
La pregunta similar ya existe en SO. – joeforker
No creo que la predicción de salto sea importante porque una búsqueda lineal también tiene ramas. Y que yo sepa, no hay SIMD que pueda hacer una búsqueda lineal por usted.
Dicho esto, un modelo útil sería suponer que cada paso de la búsqueda binaria tiene un costo multiplicador C.
log C n = n
Así para razonar sobre esto sin comparar realmente, harías una conjetura para C, y una vuelta n para el siguiente entero. Por ejemplo, si adivina C = 3, entonces sería más rápido usar la búsqueda binaria en n = 11.
He investigado esta cuestión en detalle una de resumir mis conclusiones in this blog post.
- 1. Más rápido que la búsqueda binaria para la lista ordenada
- 2. búsqueda binaria vs árbol de búsqueda binaria
- 3. Búsqueda binaria en Erlang en lg (n) tiempo
- 4. ¿Cuál es la diferencia entre la búsqueda lineal y la búsqueda binaria?
- 5. ¿Hay una búsqueda binaria incorporada en Ruby?
- 6. binaria eficiencia de búsqueda vs. eficiencia de búsqueda lineal en FORTRAN
- 7. Búsqueda binaria en matriz
- 8. Qué colección .NET proporciona la búsqueda más rápida
- 9. búsqueda binaria en una matriz en Perl
- 10. ¿Por qué los árboles de búsqueda binaria?
- 11. ¿Hay alguna manera de evitar la búsqueda lineal en esto?
- 12. Implementar búsqueda binaria en objetos
- 13. Búsqueda binaria C++ STL
- 14. Búsqueda binaria genérica en C#
- 15. ¿La búsqueda de sección dorada es mejor que la búsqueda binaria?
- 16. Búsqueda binaria sin sucursales
- 17. Problemas de búsqueda binaria?
- 18. Haciendo una búsqueda binaria sobre algunos elementos en Haskell
- 19. Encontrando altura en Árbol de búsqueda binaria
- 20. Búsqueda binaria en clojure (implementación/rendimiento)
- 21. Árbol de búsqueda binaria en C
- 22. Árbol de búsqueda binaria para la intención específica
- 23. árbol de búsqueda binaria en C# Implementación
- 24. búsqueda binaria Árbol Transversal - preorden
- 25. La manera más eficiente para una búsqueda/búsqueda en una lista enorme (python)
- 26. ¿Cómo puedo implementar la búsqueda binaria en Perl?
- 27. Búsqueda binaria en D 2.0 (Phobos)?
- 28. contenedor para la búsqueda rápida de nombres
- 29. ¿Cómo hace un diccionario una búsqueda rápida
- 30. Cómo implementar una api más rápida de búsqueda como tipo (SAYT) en la aplicación Rails 3
Esto dependerá del costo de las comparaciones en los datos en la pregunta – bdonlan
OP especificó, muy clara y explícitamente, que está hablando de una serie de _integers_ - ¿¡qué otras variaciones está PREOCUPANDO ?! –