Wie kommt es, dass sed so schnell ist?

7

Ich habe darüber nachgedacht, ob diese Frage für SE geeignet ist oder nicht. Ich hoffe, Sie stimmen dem zu.

Vor einiger Zeit habe ich auf SE gefragt, wie man Text in Dateien findet und die Datei nur mit den passenden Zeilen belässt, die den gesuchten Text enthalten. Die Frage ist hier: Wie finde ich Text in Dateien und behalte nur die entsprechenden übereinstimmenden Zeilen über das Terminal unter OS X bei?

Während die Antwort perfekt funktionierte, frage ich mich jetzt, warum sedes so schnell geht. In meinem Anwendungsfall hatte ich ziemlich viele Dateien, die insgesamt etwa 30 GB groß waren. Der sedBefehl lief in ungefähr 12 Sekunden, was ich nie geglaubt hätte (Arbeiten mit einer normalen Festplatte). Innerhalb von 12 Sekunden las der Befehl 30 GB Text durch und schnitt jede Datei ab, um nur die entsprechenden Zeilen beizubehalten, nach denen ich gefiltert habe. Wie funktioniert das? (oder: was ist das für eine Zauberei?)

Der eigentliche Befehl war:

find . -type f -exec sed -i'' '/\B\/foobar\b/!d' {} \;
Alex
quelle
Welchen Befehl haben Sie tatsächlich ausgeführt?
Cuonglm
find . -type f -exec sed -i'' '/\B\/foobar\b/!d' {} \;
Alex
1
Dies scheint eine eher allgemeine Frage zu sein. Was für eine Antwort suchten Sie? sed ist in C geschrieben und vermutlich auf Geschwindigkeit optimiert.
Faheem Mitha
Für eine allgemeine Antwort :-) aber vielleicht ausführlicher, einige technische Aspekte, was macht es, dass es so schnell ist? Wenn es einen besseren Ort gibt, um dies zu fragen, raten Sie mir bitte
Alex

Antworten:

2

Die wahrscheinliche Antwort lautet:

  1. Die 30-GB-Datei war nicht fragmentiert (oder nur sehr wenig fragmentiert): Alle Festplatten bieten eine viel bessere Leistung beim sequentiellen Zugriff (einschließlich SSDs), da sie große Teile der Datei zwischenspeichern können. Dies ermöglicht es ihnen, ihre maximale Leistung zu erreichen. Sequentieller Zugriff hilft bei allen Cache-Ebenen.
  2. sedist ein Stream-Editor; Es wird jeweils nur eine Zeile verarbeitet. Dies bedeutet, dass der Speicherbedarf winzig ist. Im Gegensatz zu einem Texteditor wie emacsoder vimmuss nicht die gesamte Kopie der Datei im Speicher gespeichert werden.
  3. Sie bearbeiten die Datei -idirekt (mit ), wodurch (wie von @Ramesh gezeigt und auch auf der Wikipedia-Seite angegeben ) temporäre Dateien erstellt werden, die dann zur alten Datei werden.

All dies bedeutet, dass sedfast das Minimum an Dateivorgängen ausgeführt werden kann: Jede Zeile der Originaldatei wird einmal gelesen und nur die übereinstimmenden Zeilen werden geschrieben.

Ihre Wahl der regulären Ausdrücke wirkt sich auch auf die Leistung aus, manchmal auf sehr schlechte Weise: Codierung des Horror-Blogs .

Superdesk
quelle
3

Ein wunderbares Beispiel ist die sedVerwendung einer temporären Datei, um den Inhalt tatsächlich zu speichern und dann die Originaldatei zu ersetzen. Sie können beispielsweise einen einfachen Test durchführen, um dies zu ermitteln.

cat test
This is a test file. 

Führen Sie nun aus ls -li, um die Inode-Nummer zu überprüfen.

ls -li test
2368770 -rw-r--r-- 1 root root 22 Sep 12 08:46 test

Geben Sie nun den folgenden sedBefehl ein, um eine Leerzeile hinzuzufügen.

sed -i 's/2/B/' test

Geben Sie nach dem Ändern der Datei den lsBefehl erneut aus und überprüfen Sie die Inode-Nummer.

ls -li test
2368753 -rw-r--r-- 1 root root 22 Sep 12 08:48 test

Wir können sehen, dass sich die Inode-Nummer tatsächlich geändert hat. Anstatt in dieselbe Datei zu kopieren, sedwird eine neue temporäre Datei erstellt und der Inhalt in die neue temporäre Datei kopiert. Anschließend wird die Originaldatei gelöscht und die tmp-Datei synchron mit der Originaldatei umbenannt. Dies ist einer der Gründe, warum die Dateivorgänge wirklich schneller sind .

Zitat aus der Wikipedia-Seite ,

sed ist ein zeilenorientiertes Textverarbeitungsprogramm: Es liest Text zeilenweise aus einem Eingabestream oder einer Eingabedatei in einen internen Puffer, der als Musterbereich bezeichnet wird. Jede gelesene Zeile startet einen Zyklus. Auf den Musterbereich wendet sed eine oder mehrere Operationen an, die über ein sed-Skript angegeben wurden. sed implementiert eine Programmiersprache mit etwa 25 Befehlen, die die Operationen für den Text angeben. Nach dem Ausführen des Skripts gibt sed für jede Zeile normalerweise den Musterraum aus (die vom Skript geänderte Eingabezeile) und beginnt den Zyklus erneut mit der nächsten Zeile.

Um mehr über den Musterraum und die Speicherraumkonzepte von zu erfahren sed, sollten Sie die Antwort hier lesen .

Wenn sed eine Datei zeilenweise liest, wird die aktuell gelesene Zeile in den Musterpuffer (Musterraum) eingefügt. Der Musterpuffer ähnelt dem temporären Puffer, dem Notizblock, auf dem die aktuellen Informationen gespeichert sind. Wenn Sie sed anweisen, zu drucken, wird der Musterpuffer gedruckt.

Hold Buffer / Hold Space ist wie ein Langzeitspeicher, sodass Sie etwas abfangen, speichern und später wiederverwenden können, wenn sed eine andere Zeile verarbeitet. Sie verarbeiten den Haltebereich nicht direkt, sondern müssen ihn kopieren oder an den Musterbereich anhängen, wenn Sie etwas damit tun möchten.

Ramesh
quelle