Puedo asegurarle, la función strcmp
es ABSOLUTAMENTE NO el cuello de botella. Normalmente, strcmp está bien optimizado y puede hacer comparaciones de 32 o 64 bits para cadenas de más de 4/8 bytes, dependiendo de la arquitectura. Tanto newlib como GNU libc hacen esto. Pero incluso si tuvieras que mirar cada byte en ambas cadenas 20 veces, no importa tanto como las opciones de estructura de datos de algo & aquí.
El cuello de botella real es el algoritmo de búsqueda O (N). Un solo pase O (N log N) en el archivo podría usarse en una estructura de datos apropiada (ya sea una BST normal, una trie o simplemente una matriz ordenada simple) para realizar búsquedas O (log N).
Tenga paciencia aquí - muchas matemáticas siguen. Pero creo que esta es una buena oportunidad para ilustrar por qué la elección de la estructura de datos del algoritmo & a veces es mucho más importante que el método de comparación de cadenas. Steve toca esto, pero quería explicarlo un poco más.
Con N = 1e6, log (1e6, 2) = 19.9, así que redondee hasta 20 comparaciones en una estructura de datos ideal.
Actualmente realiza una búsqueda de peor caso de operaciones O (N) o 1e6.
Digamos que acaba de construir un árbol rojo-negro con O (log N) tiempo de inserción e inserta N elementos, ese es el tiempo O (N log N) para construir el árbol. Así que eso es 1e6 x 20 o 20e6 operaciones necesarias para construir su árbol.
En su enfoque actual, la construcción de la estructura de datos es O (N), o operaciones 1e6, pero su peor tiempo de búsqueda de casos es O (N) también. Entonces, cuando lee el archivo y hace solo 20 operaciones de búsqueda, alcanza el peor caso teórico de 21,000,000 de operaciones. En comparación, su peor caso con un árbol rojo oscuro y 20 búsquedas es 20,000,400 operaciones, o 999,600 operaciones MEJOR que la búsqueda O (N) en una matriz no ordenada. Entonces, en 20 búsquedas, estás en el primer punto donde una estructura de datos más sofisticada realmente vale la pena. Pero mire lo que sucede en 1000 búsquedas:
array no ordenado = inicialización + 1000 x tiempo de búsqueda = O (N) + 1000 * O (N) = 1,000,000 + 2,000,000,000 = 2,001,000,000 operaciones.
Rojo-negro = inicialización + 1000 x tiempo de búsqueda = O (N log N) + 1000 * O (log N) = 20,000,000 + 20,000 = 20,020,000 operaciones.
2.001.000.000/20.020.000 ~ = 100x como muchas operaciones para el O (N) de búsqueda.
En 1e6 búsquedas, eso es (1e6 + 1e6 * 1e6)/(20e6 + 1e6 * 20) = 25,000x tantas operaciones.
Suponga que su equipo puede manejar las operaciones 40e6 '' que se necesita para hacer las búsquedas de registro N en 1 minuto. Tomaría 25,000 minutos o 17 DÍAS para hacer el mismo trabajo con su algoritmo actual. O bien, otra forma de observar es que el algoritmo de búsqueda O (N) solo puede manejar 39 búsquedas en el tiempo que el algoritmo O (log N) puede hacer 1,000,000. Y cuantas más búsquedas hagas, más feo será.
Ver las respuestas de Steve y dirkgently para varias opciones mejores de estructuras de datos & algoritmos. Mi única precaución adicional sería que qsort()
sugerido por Steve fuerza tienen un peor caso de complejidad de O (N * N), que es mucho, mucho peor que el de O (N log N) se obtiene con un heapsort o varios estructuras parecidas a árboles.
Si puede ordenar líneas, seguro. – dbrank0
Si puede hash, hash. – wildplasser
@KingsIndian: No, porque la verdadera cuestión aquí no es "cómo comparar dos cadenas", que es "la forma de probar una cadena de contención en una gran colección de cadenas". –