[Python-de] strings zusammensetzen.

Peter J. Holzer hjp-usenet3 at hjp.at
So Sep 17 06:34:45 EDT 2017


On 2017-09-17 06:19, Stefan Behnel <python-de at behnel.de> wrote:
> Peter J. Holzer schrieb am 16.09.2017 um 22:46:
>> Gerade bei langen Listen sollte man darauf verzichten, sie
>> aufzubauen, wenn man sie nicht unbedingt braucht
>
> Natürlich. Einzig darauf zielt dein Beispielcode ja auch ab.
>
> Gilt übrigens genauso für lange Strings.

Natürlich. Wenn man den langen String nie braucht, soll man ihn auch
nicht aufbauen. Gerade, wenn der String an einen Konsumenten geschickt
werden soll, der ihn dann gleich wieder parst, hat man auch noch den
Vorteil, dass Produzent und Konsument sich zeitlich überlappen können,
wenn der Produzent Teile des Outputs so früh wie möglich schickt. Geht
aber leider nicht immer: Manche Protokolle brauchen z.B. eine
Längenangabe im Header und dafür muss man den Output erst mal komplett
haben, um die Länge bestimmen zu können.

>> (habe damit erst kürzlich 8 GB eingespart - pro Prozess (das war Perl
>> und nicht Python, aber die beiden Sprachen sind sich da sehr
>> ähnlich)).
>
> Wie du hier korrekt andeutest, handelt es sich bei dem gegebenen Fall um
> eine Optimierung. Optimierung bedeutet ja, dass du eigentlich gut
> geschriebenen Code ersetzt durch etwas, was dem spezifischen Anwendungsfall
> stärker angepasst ist und (nachweislich) unter den erwarteten Bedingungen
> effizienter funktioniert. Mit dem Risiko, dass es unter anderen (eben nicht
> erwarteten) Bedingungen vielleicht auch weniger gut funktioniert.

Richtig. Wobei in diesem Fall allerdings beide Varianten von der
Code-Länge und Lesbarkeit her ziemlich vergleichbar waren. Im Gegensatz
zu manchen anderen Fällen, wo es klar eine "saubere" und eine optimierte
Variante gibt, gab es hier zwei Varianten, die zwar verschiedenen
Ansätzen (eher prozedural und eher funktional) folgten, aber (für meinen
Geschmack) beide gleich sauber waren. Da dann die Variante zu wählen,
die weniger Speicher braucht und schneller ist, ist ein No-Brainer (und
ja, ich habe beide Varianten gebenchmarkt, bevor ich die Änderung
durchgeführt habe).

Bei dem kleinen Test-Programm sehe ich das ähnlich: Die Variante mit
join ist *nicht* klar sauberer. Eher im Gegenteil: Sie baut explizit
eine unnötige Datenstruktur auf, das empfinde ich als unelegant. (Etwas
anderes ist es, wenn die Datenstruktur nur implizit aufgebaut wird: Mit
map statt der explizitien Schleife (was bei diesem Trivialbeispiel
natürlich leicht möglich gewesen wäre) wäre der Code für mich eindeutig
eleganter und damit wäre eine möglich Optimierung nur sinnvoll, wenn die
positiven Effekte zur Laufzeit die negativen Effekte für den
Programmierer überwiegen.)

Aber im wesentlichen ging es mir eben um Deine dogmatisch vorgetragene
Aussage:

| join() ist in jedem Fall die bessere Variante bei vielen Strings.

Das sehe ich eben nicht so. Gerade bei vielen Strings gibt es Fälle, wo
es besser ist, den String stückweise in einer Schleife aufzubauen.

| Konkatenierung ist ok bei einer überschaubaren Menge und da
| insbesondere bei kurzen Strings, sollte aber in Schleifen vermieden
| werden.

Und wie nun ausführlich begründet, sehe ich das genau umgekehrt: Bei
kurzen Strings, die aus wenigek Komponenten zusammengesetzt werden, ist
beides Ok. Bei langen Strings, die aus vielen Komponenten aufgebaut
werden, sollte man sich überlegen, ob nicht eine explizite Schleife
besser ist als ein Join.

        hp


-- 
   _  | Peter J. Holzer    | Fluch der elektronischen Textverarbeitung:
|_|_) |                    | Man feilt solange an seinen Text um, bis
| |   | hjp at hjp.at         | die Satzbestandteile des Satzes nicht mehr
__/   | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel


Mehr Informationen über die Mailingliste python-de