Náhodou som dnes na jednom blogu natrafil na jedej príspevok, kde autor publikoval skript pre zobrazovanie informácií o stave systému v grafickom prostredí. Skript je pekný, ďakujem za inšpiráciu, ale trpí jedným neduhom – príliš komplikované a príliš pomalé získavanie dát.
Pritom optimalizácia je pomerne jednoduchá: stačí lepšie využit vlastnosti jednotlivých nástrojov (prípadne použiť vhodnejší 🙂 ) a celý beh skriptu je možné dramaticky zrýchliť. Pre porovnanie som spravil nasledujúci test a výsledky sú veľmi zaujímavé. Nasledujúci fragment kódu zmeria čas, za ktorý sa zistí počet bajtov prenesených sieťovým rozhraním 10.000 krát.
Stará verzia kódu pred optimalizáciou
$ time for i in `seq 1 10000`; do var_eth0_rx_new=$(cat "/proc/net/dev" | grep eth0 | sed 's/[a-zA-Z \t:()]\+/ /g' | cut -d ' ' -f 3) ; done real 6m22.510s user 0m2.530s sys 6m14.263s
Nová verzia po jednoduchej optimalizácii
$ time for i in `seq 1 10000`; do var_eth0_rx_new=$( awk -v FS='[ :]+' '$2 == "eth0" { print $3; }' /proc/net/dev ); done real 1m49.656s user 0m0.898s sys 1m48.338s
Vidíme teda, že nový kód beží takmer 3,5x rýchlejšie. Čas, ktorý strávil kernel náročným forkovaním veľkého počtu procesov dramaticky klesol (40.000 forkov v prvom prípade vs. 10.000 forkov v druhom prípade).
Ďalší príklad
-var_load=$(cat /proc/loadavg | cut -d " " -f 1) +var_load=$(cut -d " " -f 1 /proc/loadavg)
Optimalizujeme teda podľa nasledovných pravidiel:
- názov súboru môžeme dať príkazu
cut
ako parameter, nemusíme používaťcat | cut
- prvý bod platí aj pre
grep
,sed
aawk
- počet rúr
|
sa snažíme minimalizovať - sekvenciu
cat | grep | sed | cut
možno poväčšinou nahradiť jednýmawk
Jediný pozor si musíme dávať iba vtedy, ak píšeme skript pre viac platforiem. Vtedy je dobré funkčnosť skriptu pred nasadením riadne preveriť, pretože nie každý unix systém má zhodnú verziu awk
a taktiež pozor na bashismy.