Michael Lange: >> Jochen Spieker <ml@well-adjusted.de> wrote: > >>> Doch, in der asymptotischen Betrachtung schon. :) Du baust den >>> String >>> PKGS pro Paket neu (n mal) und dabei wird er immer länger. Der erste >>> Paketname wird n-1 mal kopiert, der zweite n-2 und so weiter. Das ist >>> einfach ein schlechter Algorithmus. Die Laufzeit steigt >>> überproportional zur Länge der Paketliste. Sowas will man >>> grundsätzlich vermeiden. > > Ist mir im Prinzip natürlich klar, der naheliegende Ansatz wäre eher, > nicht in INSTALLED_PKGS vorhandene Einträge aus PKGNAMES zu entfernen, > allerdings geht das mit der Shell selbst nicht (soweit ich weiss > zumindest), und eine Pipe mit sed oder so zu benutzen wird auch bei > relativ wenigen zu eliminierenden Paketen schnell sehr ineffizient. Dafür verwende ich gerne grep. Wenn INSTALLED_PKGS und PKGNAMES in entsprechend benannten Dateien sind (ein Paket pro Zeile, Sortierung egal): grep -v -f INSTALLED_PKGS PKGNAMES -v gibt Dir *nicht* matchende Zeilen aus, -f $file liest die Patterns aus $file. In diesem konkreten Fall würde ich auch noch -F ("fixed strings") entfernen. Das schaltet den Regex-Parser in grep aus und macht es deutlich schneller. > Ich habe jetzt noch testweise mal ausprobiert, wie gross die Verzögerung > durch das wiederholte verändern von PKGS ist. Die for-Schleife lief > (sowohl in dash als auch bash) jew. ca. 10% schneller, wenn die > entspr. Zeile auskommentiert wird (die Schleife also durchläuft ohne > wirklich etwas zu tun). Zweifellos nicht schön, aber andererseits ist > performance-technisch wohl eher die Schleife an sich das Problem. Oder vielleicht das case-Statement? Das Pattern ist sicher teuer. > Ok, durch herumprobieren herausgefunden, die Anfühungzeichen um $p > entfernen und die Leerzeichen durch Backslash maskieren scheint die > Posix-konforme Variante zu sein: > > for p in $PKGNAMES; do > case " $INSTALLED_PKGS " in > *\ $p\ *) > PKGS="$PKGS $p";; > esac > done Warum nimmst Du überhaupt case, wenn Du nur einen Fall hast? Mir erscheint die Prüfung auch von der Logik her irgendwie falschrum. Du könntest auch so prüfen: if [[ "$INSTALLED_PKGS" =~ "$p" ]] ; then echo huhu; fi > (falls jemand ein gutes Tutorial kennt, aus dem man solche Dinge lernen > kann, wäre ich dankbar für einen Link :) Leider nein. Das oben dürfte auch bash-spezifisch sein. Portabel würde ich das mit echo und grep lösen. Würde mich nicht wundern, wenn das besser performt, als das Pattern mit Wildcards vorne und hinten. J. -- I believe there is a world of wealth, fashion and elegance that will be forever denied to me. [Agree] [Disagree] <http://archive.slowlydownward.com/NODATA/data_enter2.html>
Attachment:
signature.asc
Description: Digital signature