Ich bin wirklich erstaunt über die Funktionalität von GREP in der Shell. Früher habe ich die Teilstring-Methode in Java verwendet, aber jetzt verwende ich GREP dafür und es wird in Sekundenschnelle ausgeführt. Es ist unglaublich schneller als der Java-Code, den ich früher geschrieben habe. (Nach meiner Erfahrung könnte ich mich jedoch irren)
Davon abgesehen konnte ich nicht herausfinden, wie es passiert? Es ist auch nicht viel im Web verfügbar.
Kann mir jemand dabei helfen?
Antworten:
Angenommen, Ihre Frage bezieht sich
GNU grep
speziell. Hier ist eine Notiz des Autors Mike Haertel:Diese Antwort ist eine Teilmenge der hier entnommenen Informationen .
quelle
Zu Steves hervorragender Antwort hinzufügen.
Es ist vielleicht nicht allgemein bekannt, aber grep ist fast immer schneller, wenn nach einer längeren Pattern-Zeichenfolge gesucht wird als nach einer kurzen, da Boyer-Moore in einem längeren Pattern in längeren Schritten vorwärts springen kann, um noch bessere sublineare Geschwindigkeiten zu erzielen :
Beispiel:
Die längere Form ist 35% schneller!
Woher? Boyer-Moore erstellt aus der Musterzeichenfolge eine Sprung-Vorwärts-Tabelle. Wenn eine Nichtübereinstimmung vorliegt, wird der längste mögliche Sprung (vom letzten zum ersten Zeichen) ausgewählt, bevor ein einzelnes Zeichen in der Eingabe mit dem Zeichen in der Sprung-Tabelle verglichen wird.
Hier ist ein Video, das Boyer Moore erklärt (Dank an kommradHomer)
Ein weiteres häufiges Missverständnis (für GNU grep) ist, dass
fgrep
es schneller ist alsgrep
.f
infgrep
steht nicht für 'schnell', sondern für 'fest' (siehe Manpage), und da beide dasselbe Programm sind und beide Boyer-Moore verwenden , gibt es keinen Unterschied in der Geschwindigkeit zwischen ihnen bei der Suche nach fest- Zeichenfolgen ohne reguläre Zeichen. Der einzige Grund , warum ich Gebrauchfgrep
ist , wenn es gibt ein regexp spezielles Zeichen (wie.
,[]
, oder*
) Ich will sich nicht als solche interpretiert werden. Und selbst dann wird die tragbarere / Standardform vongrep -F
bevorzugtfgrep
.quelle
xs.txt
enthält 100000000 'x, und Sie tun diesgrep yx xs.txt
, dann findet sie tatsächlich keine Übereinstimmung früher als wenn Sie dies tungrep yxxxxxxxxxxxxxxxxxxx xs.txt
. Die Verbesserung von Boyer-Moore-Horspool gegenüber Boyer-Moore verbessert in diesem Fall das Überspringen, aber im allgemeinen Fall werden es wahrscheinlich nicht nur drei Maschinenanweisungen sein.grep/fgrep/egrep
alle Hardlinks zu derselben ausführbaren Datei waren, vorbei sind. Sie (und andere Erweiterungen wie diez*grep
bz*grep
Utils, die im laufenden Betrieb dekomprimiert werden) sind jetzt kleine Shell-Wrappergrep
. Einige interessante historische Kommentare zum Wechsel zwischen einer einzelnen ausführbaren Datei und Shell-Wrappern finden Sie in diesem Commit: git.savannah.gnu.org/cgit/grep.git/commit/…