GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie kann ich dieses Sed-Skript schneller machen?

Meine Tests haben ergeben, dass sed kann bei so etwas ziemlich leicht CPU-gebunden werden. Wenn Sie einen Computer mit mehreren Kernen haben, können Sie versuchen, mehrere sed zu spawnen Prozesse mit einem Skript, das in etwa so aussieht:

#!/bin/sh
INFILE=data.txt
OUTFILE=fixed.txt
SEDSCRIPT=script.sed
SPLITLIMIT=`wc -l $INFILE | awk '{print $1 / 20}'`

split -d -l $SPLITLIMT $INFILE x_

for chunk in ls x_??
do
  sed -f $SEDSCRIPT $chunk > $chunk.out &
done

wait 

cat x_??.out >> output.txt

rm -f x_??
rm -f x_??.out

Versuchen Sie, die ersten beiden Zeilen zu ändern:

s/[ \t]*|[ \t]*/|/g

Das Beste, was ich mit sed machen konnte, war dieses Skript:

s/[\s\t]*|[\s\t]*/|/g
s/[\s\t]*$//
s/^|/null|/

In meinen Tests lief dies etwa 30 % schneller als Ihr sed-Skript. Die Leistungssteigerung ergibt sich aus der Kombination der ersten beiden regulären Ausdrücke und dem Weglassen des "g"-Flags, wo es nicht benötigt wird.

30 % schneller ist jedoch nur eine leichte Verbesserung (es sollte immer noch etwa anderthalb Stunden dauern, um das obige Skript auf Ihrer 1-GB-Datendatei auszuführen). Ich wollte sehen, ob ich es besser machen könnte.

Am Ende schnitt keine andere Methode, die ich ausprobiert habe (awk, perl und andere Ansätze mit sed), besser ab, außer natürlich einer einfachen alten C-Implementierung. Wie bei C zu erwarten, ist der Code etwas ausführlich, um ihn hier zu posten, aber wenn Sie ein Programm suchen, das wahrscheinlich schneller ist als jede andere Methode da draußen, sollten Sie es sich vielleicht einmal ansehen.

In meinen Tests ist die C-Implementierung in etwa 20 % der Zeit abgeschlossen, die für Ihr Sed-Skript benötigt wird. Es kann also ungefähr 25 Minuten dauern, bis es auf Ihrem Unix-Server läuft.

Ich habe nicht viel Zeit damit verbracht, die C-Implementierung zu optimieren. Zweifellos gibt es eine Reihe von Stellen, an denen der Algorithmus verbessert werden könnte, aber ehrlich gesagt weiß ich nicht, ob es möglich ist, über das hinaus, was er bereits erreicht, erheblich Zeit zu sparen. Wenn überhaupt, denke ich, dass es sicherlich eine Obergrenze dafür setzt, welche Art von Leistung Sie von anderen Methoden (sed, awk, perl, python usw.) erwarten können.

Bearbeiten: Die Originalversion hatte einen kleinen Fehler, der dazu führte, dass am Ende der Ausgabe möglicherweise das Falsche gedruckt wurde (z. B. konnte eine "Null" gedruckt werden, die nicht dort sein sollte). Ich hatte heute etwas Zeit, um es mir anzusehen und das zu beheben. Ich habe auch einen Aufruf von strlen() wegoptimiert das gab ihm einen weiteren leichten Leistungsschub.


Linux
  1. Wie kann man Umgebungsvariablen „exportiert“ in einem Shell-Skript bleiben lassen?

  2. Wie debuggt man ein Bash-Skript?

  3. Warum ist SCP so langsam und wie kann man es schneller machen?

  4. Wie man ein Skript ausführt??

  5. So lässt sich meine Website schneller laden

Wie man eine Datei unter Linux ausführbar macht

So machen Sie ein Linux-System schneller auf Intel-CPUs

So navigieren Sie unter Linux schneller durch Verzeichnisse

Wie man Debian Linux schneller macht

So führen Sie ein Python-Skript in PHP aus

So führen Sie ein Bash-Skript aus