Unix grep funziona più velocemente con termini di ricerca lunghi o brevi?


8

È più veloce cercare termini di ricerca lunghi o brevi? O influenza la velocità? In altre parole, dovresti rendere i termini di ricerca il più esatti possibile?

Esistono più di 100000 file e ogni file contiene tra 20 e più di 5000 righe di dati. Di solito grep è usato per trovare solo un'istanza del termine di ricerca.

Supponiamo che il termine di ricerca sia SEARCHTERM, e sarà in una riga come questo:

NAD+DP+1234567890:92++UNIQUE+NAME+SEARCHTERM++12345+FI'

È più veloce cercare "RICERCA" o "RICERCA"? Diciamo che in questo caso non ci interessa se troviamo anche corrispondenze in altre linee non correlate.

Ecco come lo faccio attualmente:

grep NAD+DP 123* | grep SEARCHTERM

Ma lo trovo abbastanza lento, fermo. Di solito ci vogliono circa 3-5 minuti per trovare i dati, anche quando conosco il nome del file approssimativo, che limita l'intervallo a circa 10.000 file.

Quindi, sarebbe utile un termine di ricerca più lungo o più breve? Per quanto ne so, grep cerca "blocchi" di parole di una certa lunghezza?

Risposte:


8

Qualche materiale di riferimento:

GNU grep usa il noto algoritmo Boyer-Moore, che cerca prima la lettera finale della stringa di destinazione e usa una tabella di ricerca per dirgli quanto può saltare l'input ogni volta che trova un carattere non corrispondente.

da Perché GNU grep è veloce .

L'algoritmo preelabora la stringa cercata (il modello), ma non la stringa cercata (il testo). [...] In generale, l'algoritmo corre più veloce all'aumentare della lunghezza del modello.

da Algoritmo di Boyer-Moore .

Conclusione: utilizzare stringhe più lunghe .

Ora, un po 'di benchmark per divertimento:

# Initialisation
cd $(mktemp -d) && dd if=/dev/urandom of=random bs=1M count=1000
# Version
grep --v` # grep (GNU grep) 2.9
# Benchmark
(for s in 'short' 'this is not so short and we could even consider this as pretty long'; do for t in {1..10}; do time grep "$s" random; done; done ) 2> result

Risultati: 0.952s è la media per la stringa corta, 0.244s è la media per la stringa lunga.

NB : la lunghezza non è l'unico criterio da prendere in considerazione.


0

Puoi provare te stesso usando SEARCH o SEARCHTERM. Prova anche a cambiare l'ordine dei due comandi grep. Ad ogni modo l'unica opzione utile sarà molto probabilmente quella di utilizzare più core della CPU per una ricerca. Vedi il parallelcomando


0

Non penso che specificare un termine di ricerca più specifico lo renderà notevolmente più veloce.

Con così tanti file da cercare, devi in ​​qualche modo indicizzare i tuoi dati per velocizzare la ricerca.

Posso suggerire alcuni modi:

  • Crea database (PostgreSQL o MySQL), importa i tuoi dati nel database - un file in una riga, aggiungi l'indice FTS (ricerca di testo completo). Crea qualche utilità per interrogare il database.

  • Importa i dati nel database in modo più granulare, probabilmente una riga in una riga (o forse più di una tabella), crea indici in modo tale che i tuoi dati siano ricercabili utilizzando gli indici. Crea qualche utilità per interrogare il database.

  • Aggiungi i tuoi file al gitrepository, compattalo usando git gc, usa git grepper cercare. Nella mia esperienza, git greppuò essere più veloce dello standard grepcon un fattore di 10x-100x.


0

Logicamente, un termine più breve richiederà meno tempo della CPU, come grepfarà

if (filechar[i] == pattern[i]) ...

meno volte. In realtà, immagino che a grepsia associato a I / O e non a CPU, quindi non importa.


1
Abbastanza sorprendentemente, questo è sbagliato poiché grep sta usando un algoritmo davvero intelligente, fare riferimento alla mia risposta.
SylvainD,

più lunga è la stringa di ricerca, più caratteri può saltare quando trova una discrepanza, quindi la ricerca sarà più veloce
phuclv,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.