GNU/Linux >> Znalost Linux >  >> Linux

Jak zrychlit tento sed skript?

Moje testování ukázalo, že sed se na něčem takovém může docela snadno stát CPU vázáno. Pokud máte vícejádrový počítač, můžete zkusit vytvořit několik sed procesy se skriptem, který vypadá asi takto:

#!/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

Zkuste změnit první dva řádky na:

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

To nejlepší, co jsem se sedem dokázal udělat, byl tento scénář:

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

V mých testech to běželo asi o 30 % rychleji než váš skript sed. Zvýšení výkonu pochází z kombinace prvních dvou regulárních genů a vynechání příznaku „g“ tam, kde to není potřeba.

O 30 % rychlejší je však jen mírné zlepšení (spuštění výše uvedeného skriptu na vašem 1GB datovém souboru by stále mělo trvat asi hodinu a půl). Chtěl jsem zjistit, jestli bych mohl udělat něco lepšího.

Nakonec žádná jiná metoda, kterou jsem zkoušel (awk, perl a další přístupy se sed), nedopadla lépe, kromě -- samozřejmě -- obyčejné implementace v C. Jak by se dalo očekávat u C, kód je pro zveřejňování zde trochu podrobný, ale pokud chcete program, který bude pravděpodobně rychlejší než jakákoli jiná metoda, můžete se na něj podívat.

V mých testech implementace C skončí asi za 20 % času, který zabere váš skript sed. Takže spuštění na vašem Unixovém serveru může trvat asi 25 minut.

Optimalizací implementace C jsem moc času nestrávil. Není pochyb o tom, že existuje řada míst, kde by se dal algoritmus vylepšit, ale upřímně řečeno, nevím, jestli je možné holit značnou dobu nad rámec toho, čeho již dosahuje. Pokud něco, myslím, že to určitě stanoví horní hranici toho, jaký druh výkonu můžete očekávat od jiných metod (sed, awk, perl, python atd.).

Upravit: Původní verze měla drobnou chybu, která způsobila, že na konci výstupu možná vytiskla špatnou věc (např. mohla vytisknout „null“, která by tam neměla být). Dnes jsem měl čas se na to podívat a opravit to. Také jsem optimalizoval volání na strlen() což mu dalo další mírné zvýšení výkonu.


Linux
  1. Jak zpětně zajistit, aby skript běžel jako root?

  2. Jak zajistit, aby příkaz alias fungoval ve skriptu bash nebo souboru bashrc

  3. Jak testovat PHP skript

  1. Jak zajistit, aby byly proměnné prostředí „exportovány“ do skriptu Shell?

  2. Jak ladit Bash skript?

  3. Jak zajistit, aby skript Python běžel jako služba nebo démon v Linuxu

  1. Proč je scp tak pomalý a jak jej urychlit?

  2. Jak spustit skript??

  3. Jak zrychlit načítání webu