Hoher Speicherbedarf bei "Einzeilern"?

Code-Stücke können hier veröffentlicht werden.
Antworten
thyrc
User
Beiträge: 3
Registriert: Dienstag 25. März 2008, 12:04
Wohnort: Taibei

Dienstag 25. März 2008, 12:49

Ich habe Frage zu einem Python one-liner... ich habe vor ein paar Tagen aus purer Neugierde einmal verschiedene Einzeiler (also kurze Scripte in awk, Perl, sed usw.) mit einander verglichen. Und ich wollte der Vollständigkeit halber auch Python in meinen kleinen Parcours mit aufnehmen.

Aufgabe war (und ist) in einer recht großen Text-Datei (200+ MB) eine vierstellige Nummer durch "0000" zu ersetzen. Also habe ich mir mit Hilfe der Python Wiki folgen Code ausgedacht:

Code: Alles auswählen

python -c "import sys,re; print re.sub('X-Mozilla-Status: [0-9]{4}','X-Mozilla-Status: 0000', sys.stdin.read())," < Inbox > null
bzw.

Code: Alles auswählen

python -c "import re,sys,fileinput; [sys.stdout.write(re.sub('X-Mozilla-Status: [0-9]{4}', 'X-Mozilla-Status: 0000', line)) for line in fileinput.input('Inbox')]" > null
Soweit funktionieren die Scripte auch einwandfrei, nur in Sachen Speicherbedarf bin ich etwas stutzig geworden.

Die sys.stdin.read() Version arbeitet sehr zügig, verbrät aber bis zu 600MB RAM auf meinen System. Soweit nicht verwunderlich, da erst die komplette Datei gelesen und erst dann verarbeitet wird.

Die fileinput.input Version braucht auf meinem System an die 19 MB Speicher, schon besser... braucht aber auch ca. 3 mal so lange.

Nun aber endlich zum Knackpunkt: Wenn ich die fileinput.input Version statt in der Kommandozeile in einem Script ausühre,

Code: Alles auswählen

#!/usr/bin/env python

import sys,re,fileinput;

for line in fileinput.input():
    print re.sub('X-Mozilla-Status: [0-9]{4}', 'X-Mozilla-Status: 0000', line),
sinkt der Speicherbedarf auf knapp 4,5 MB. Die Geschwindigkeit, bzw. Langsamkeit bleibt gleich.

Hab ich einen Fehler gemacht? (Denkbar, ich hab wirklich gerade erst angefangen mit Python zu arbeiten...) Gibt es eine elegantere Lösung?

Für einen kleinen Schubs in die richtige Richtung wäre ich euch mächtig dankbar,
thyrc
BlackJack

Dienstag 25. März 2008, 13:44

Deine zweite Variante enthält eine "list comprehension" die eine Liste aus ganz vielen `None`\s aufbaut. Eins pro Zeile in der Datei.
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Dienstag 25. März 2008, 14:09

Code: Alles auswählen

python -c "import re,sys,fileinput; sys.stdout.writelines(re.sub('[0-9]{4}', '0000', line) for line in fileinput.input())" > null
So sollte es recht fix klappen :]
thyrc
User
Beiträge: 3
Registriert: Dienstag 25. März 2008, 12:04
Wohnort: Taibei

Mittwoch 26. März 2008, 07:20

Vielen Dank für die schnellen Antworten,

@BlackJack
Das muss es wohl sein. Ich hatte nur über "list comprehensions" gelesen, dass sie oft eine bessere Verarbeitungsgeschwindigkeit bieten als sequence operations oder list Methoden... in diesem Fall wohl eher nicht.
I will learn, eventually, wie gesagt, ich stehe erst ganz am Anfang.

@audax
Die writelines Methode bringt mich leider auch nicht wirklich weiter. Der Speicherbedarf bleibt in etwa gleich nur die Verarbeitungsgeschwindigkeit sinkt erheblich (in meinem Fall von ca. 20 Sekunden mit write auf ca. 55s mit writelines).
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 26. März 2008, 08:17

thyrc hat geschrieben:Aufgabe war (und ist) in einer recht großen Text-Datei (200+ MB) eine vierstellige Nummer durch "0000" zu ersetzen.
Und warum machst du dir da über den Speicherverbrauch Gedanken?

Schau mal bitte hier: [wiki]FAQ#WiendereIchDatenInDateien[/wiki]

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
thyrc
User
Beiträge: 3
Registriert: Dienstag 25. März 2008, 12:04
Wohnort: Taibei

Mittwoch 26. März 2008, 09:00

Ich bin von Natur aus leider ein Korinthenkacker, peinlich aber wahr... :? Neee, pure Neugier.

Ich bin über die Sache mit dem Speicherverbrauch auch nur gestolpert weil ich ein paar Tools (awk, sed, Perl) mit einander vergleichen wollte, im Bereich Performance und halt auch Speicherauslastung (Gewinner in beiden Feldern: mawk).

Bezug zur Wirklichkeit hatte der Spaß auch nur, weil ich die gelöschten Mails einer Kollegin wiederherstellen sollte und ich mit der Performance der üblichen Windows-Tools nicht zufrieden war.

Ich weiß, meine kleine Anwendung ist sehr speziell und hat auch keinerlei repräsentativen Wert. Warum mache ich mir da Gedanken über der Speicherverbrauch? Wirklich nichts als reine Neugier!

Trotzdem danke für den Link.
Antworten