GNU grep è veloce perché evita l'accesso a ogni byte di ingresso.
GNU grep è veloce perché esegue le istruzioni MOLTO POCHI PER OGNI BYTE che fa sguardo.
GNU grep utilizza il noto algoritmo di Boyer-Moore, che guarda prima per la lettera finale della stringa di destinazione, e usa una tabella di ricerca per raccontarla quanto anticipo si può saltare in ingresso ogni volta che trova a carattere non corrispondente.
GNU grep srotola anche il ciclo interno di Boyer-Moore, e imposta i Boyer-Moore voci della tabella delta in modo tale che essa non deve fare il test di uscita anello ad ogni passo srotolato. Il risultato di questo è che, nel limite, GNU grep ha una media di meno di 3 istruzioni x86 eseguite per ogni byte di input che effettivamente guarda (e salta completamente molti byte ).
GNU grep utilizza chiamate di sistema di input Unix raw ed evita di copiare i dati dopo averlo letto. Inoltre, GNU grep evita l'interruzione dell'ingresso nelle linee . La ricerca di nuove righe rallenterebbe gradualmente di un fattore pari a diverse volte, perché per trovare le nuove righe dovrebbe guardare a ogni byte!
Così, invece di utilizzare il metodo di line-oriented, GNU grep legge i dati grezzi in un buffer di grandi dimensioni, ricerche il buffer utilizzando Boyer-Moore, e solo quando trova una corrispondenza lo fa andare a cercare le nuove righe di delimitazione (Alcune opzioni della riga di comando come -n disattivare questa ottimizzazione.)
È open source, quindi puoi dare un'occhiata a te stesso. http://www.gnu.org/software/grep/devel.html – driis
@WilliamPursell Quando il tempo di esecuzione passa nei secondi, la JIT ha probabilmente scaldato e la differenza tra la mente e l'intorpidimento è dovuta a (1) essere grep incredibilmente intelligente su ciò che fa e (2) il codice Java fa una scelta algoritmo piuttosto male per il problema specifico su cui grep si focalizza. – delnan
Quanto tempo impiega la tua implementazione Java per avviare la JVM e quanto tempo impiega effettivamente l'esecuzione del codice? Oppure potrebbe essere una questione dell'algoritmo che hai usato nel tuo codice Java; un algoritmo O (N^2) rischia di essere lento in qualsiasi lingua. –