Posso assicurarvi, la funzione strcmp
NON è ASSOLUTAMENTE il collo di bottiglia. Tipicamente, strcmp è ben ottimizzato e può fare confronti a 32 o 64 bit per stringhe più lunghe di 4/8 byte a seconda dell'architettura. Sia newlib che GNU libc fanno questo. Ma anche se si guardano i byte di entrambe le stringhe per 20 volte, non importa quanto le scelte della struttura dati algo & fatte qui.
Il vero collo di bottiglia è l'algoritmo di ricerca O (N). È possibile utilizzare un singolo passaggio O (N log N) nel file alla struttura dati appropriata (che si tratti di un normale BST, di un trie o di un semplice array ordinato) per eseguire ricerche O (log N).
Orso con me qui - segue molta matematica. Ma penso che questa sia una buona opportunità per illustrare il motivo per cui la scelta della struttura dei dati dell'algoritmo & è a volte molto più importante del metodo di confronto delle stringhe. Steve tocca questo, ma volevo spiegarlo in modo un po 'più profondo.
Con N = 1e6, log (1e6, 2) = 19,9, quindi arrotondare fino a 20 confronti su una struttura dati ideale.
Attualmente si sta eseguendo una ricerca nel caso peggiore di operazioni O (N) o 1e6.
Quindi, diciamo che si costruisce un albero rosso-nero con O (log N) tempo di inserimento e si inseriscono N elementi, ovvero O (N log N) tempo per costruire l'albero. Quindi sono necessarie operazioni 1e6 x 20 o 20e6 per costruire il tuo albero.
Nel vostro attuale approccio, la costruzione della struttura dati è O (N), o operazioni 1e6, ma il tempo di ricerca nel caso peggiore è O (N). Quindi nel momento in cui leggi il file e fai solo 20 operazioni di ricerca, sei pronto per un caso teorico peggiore di 21.000.000 di operazioni. In confronto, il tuo caso peggiore con un albero rosso-nero e 20 ricerche è 20.000.400 operazioni, o 999.600 operazioni MEGLIO della ricerca O (N) su un array non ordinato. Quindi, in 20 ricerche, sei al primo punto in cui una struttura dati più sofisticata è davvero redditizia. Ma guarda cosa succede a 1000 ricerche:
Array non ordinato = inizializzazione + 1000 x tempo di ricerca = O (N) + 1000 * O (N) = 1.000.000 + 2.000.000.000 = 2.001.000.000 operazioni.
Rosso-nero = inizializzazione + 1000 x tempo di ricerca = O (N log N) + 1000 * O (log N) = 20.000.000 + 20.000 = 20.020.000 operazioni.
2,001,000,000/20,020,000 ~ = 100x tante operazioni per la ricerca O (N).
In 1e6 ricerche, è (1e6 + 1e6 * 1e6)/(20e6 + 1e6 * 20) = 25.000 volte il numero di operazioni.
Assumere che il computer sia in grado di gestire le "operazioni" 40e6 necessarie per eseguire le ricerche del registro N in 1 minuto. Ci vorrebbero 25.000 minuti o 17 GIORNI per fare lo stesso lavoro con il tuo attuale algoritmo. Oppure un altro modo di guardare è che l'algoritmo di ricerca O (N) può gestire solo 39 ricerche nel tempo in cui l'algoritmo O (log N) può fare 1.000.000. E più ricerche fai, più brutto diventa.
Vedere le risposte da Steve e dirkgently per diverse scelte migliori delle strutture di dati & algoritmi. La mia unica cautela aggiuntiva sarebbe che qsort()
suggerito da Steve potrebbe avere una complessità nel caso peggiore di O (N * N), che è molto, molto peggio di O (N log N) che si ottiene con un heapsort o vari strutture ad albero
Se è possibile ordinare le linee, sicuro. – dbrank0
Se è possibile hash, hash. – wildplasser
@KingsIndian: no, perché la vera domanda qui non è "come confrontare due stringhe", è "come testare una stringa per il contenimento in una vasta raccolta di stringhe". –