Seite 1 von 1
Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 12:54
von SVPAM
Hallo Community,
!!! Ich möchte einen Array so schnell wie möglich speichern !!!
Hierzu habe ich folgenden einfachen Quellcode:
Code: Alles auswählen
a=zeros(10000000) # Initialisierung des Array a
Time= ExecTime() # "Time"-Objekt erzeugen
Time.Start_T= time() # Start der Zeitmessung
f= open("traditional.dat","w") # Datei öffnen
for i in range(len(a)): # For-Schleife zum schreiben des Arrays a in eine Datei
f.write(str(i)+"\n")
f.close() # Datei schließen
Time.End_T= time() # Ende der Zeitmessung
Dauert auf meinem Intel core i5 Prozessor: 29 Sekunden.
(Ich habe den Quellcode, der die Dauer berechnet, der Einfachheit halber weggelassen)
Meine Frage an Euch:
Wie geht es schneller?
Ich habe bereits
writeline() und das
Pickle Modul ausprobiert, jedoch waren beide langsamer. Ihr habt bestimmt etwas, das viel schneller geht, oder?
Danke und Gruß
SVPAM
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 12:59
von Trichter
Korrigiert mich, wenn ich falsch liege, aber ist da der entscheidende Faktor nicht die Schreibgeschwindigkeit der Festplatte?
Wesentlich beschleunigen kann man das mit reiner Code-Optimierung nicht mehr.
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 13:03
von Hyperion
Abgesehen davon sollte man Dateien so öffnen:
Code: Alles auswählen
with open(...) as filehandler:
# filehandler ist hier file-object
Damit wird die Datei immer geschlossen (also auch im Fehlerfall).
Dir ist klar, dass Du nicht den Inhalt des Arrays in eine Datei schreibst, sondern einen Index? Den sollte man auch eher mittels `enumerate` erzeugen.
Strings würde ich auch nicht mittels `+` zusammensetzen, sondern `"".format()` benutzen.
Das wichtigste hat Trichter natürlich schon erwähnt. Der Sinn dieser Optimierung erschließt sich mir nicht.
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 13:05
von webspider
Code: Alles auswählen
>>> a = ["0"] * 10000000
>>> with open("test.txt", "w") as f:
... f.write("\n".join(a))
...
>>>
Dauerte eine oder zwei Sekunden. Oder mache ich was falsch?
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 13:08
von snafu
Trichter hat geschrieben:Korrigiert mich, wenn ich falsch liege, aber ist da der entscheidende Faktor nicht die Schreibgeschwindigkeit der Festplatte?
Wesentlich beschleunigen kann man das mit reiner Code-Optimierung nicht mehr.
Genau genommen sind es wohl eher die *ständigen* Schreibvorgänge. Als Alternative kann man den zu schreibenden Inhalt auch in einem Rutsch mittels `f.write('\n'.join(mein_array))` in die Datei schreiben. Einziges Manko, was aber erst bei sehr großen Arrays sichtbar wird: Auf diese Weise wird *alles* in den RAM gespeichert. Wenn wir jetzt von nem Gigabyte an Gesamtinhalt sprechen oder so, dann muss man sich etwas ausdenken, was die Sache häppchenweise erledigt. Zunächst würd ich's aber mal mit der vorgeschlagenen Lösung ausprobieren.
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 13:12
von snafu
Hyperion hat geschrieben:Dir ist klar, dass Du nicht den Inhalt des Arrays in eine Datei schreibst, sondern einen Index? Den sollte man auch eher mittels `enumerate` erzeugen.
Falls man wirklich nur den Index will (was ich allerdings auch nicht so recht glaube), dann ist `range(len(iterable))` IMHO schon ganz ok. Unter Python 2.x natürlich optimalerweise `xrange()` statt `range()`.
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 14:29
von SVPAM
Hallo Forumsmitglieder,
BÄRENSTARK! Der Array wurde in 1 Sekunde gespeichert mit dem Befehl:
Vielen Dank, das ist eine Wucht!
Zu Euren Fragen:
...ist da der entscheidende Faktor nicht die Schreibgeschwindigkeit der Festplatte? Wesentlich beschleunigen kann man das mit reiner Code-Optimierung nicht mehr.
Na ja, wie webspider eindrucksvoll gezeigt hat, kann man die Dauer doch auf ca. < 1 Sekunde reduzieren (jedenfalls habe ich die Festplatte nicht getauscht

).
`f.write('\n'.join(mein_array))` ... Auf diese Weise wird *alles* in den RAM gespeichert. ... muss man sich etwas ausdenken, was die Sache häppchenweise erledigt.
Sehr guter Einwand snafu! Das ist bei mir bereits eingetreten. Mit dieser Technik beschäftige ich mich gerade, weiß jedoch nicht genau, woher ich - bei veränderlichem Arrayinhalt - weiß, wie groß die Häppchen denn maximal sein dürfen?
Dir ist klar, dass Du nicht den Inhalt des Arrays in eine Datei schreibst, sondern einen Index?
Ähhh ... verstehe ich nicht ganz. In meinem Programm enthält das Array natürlich irgendwelche float-Werte, aber für meine Frage wollte ich es aufs Wesentliche reduzieren und der Einfachheit halber einen Array mit lauter Nullen vorstellen. Habe ich da etwas übersehen?
Vielen Dank für Eure tollen Hilfen!
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 14:35
von Hyperion
SVPAM hat geschrieben:
In meinem Programm enthält das Array natürlich irgendwelche float-Werte, aber für meine Frage wollte ich es aufs Wesentliche reduzieren und der Einfachheit halber einen Array mit lauter Nullen vorstellen. Habe ich da etwas übersehen?
Nö, das ist ja noch alles korrekt. Aber Du schreibst ja nicht die Nullen in die Datei, sondern Integer-Werte mit dem Index, also "1, 2, 3, 4, ...". Darauf wollte ich nur hinweisen.
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 14:36
von EyDu
Da du mit numpy zu arbeiten scheinst: ``numpy.save`` ist dir bekannt?
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 14:43
von SVPAM
Aber Du schreibst ja nicht die Nullen in die Datei, sondern Integer-Werte mit dem Index, also "1, 2, 3, 4, ...".
Ahhh ... jetzt! Natürlich, habe ich übersehen. Du hast natürlich Recht
``numpy.save`` ist dir bekannt?
Ja, das habe ich gleich anfangs ausprobiert, jedoch keinen Geschwindigkeitsgewinn erzielen können.
Danke Leute!
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 14:51
von snafu
SVPAM hat geschrieben:Sehr guter Einwand snafu! Das ist bei mir bereits eingetreten. Mit dieser Technik beschäftige ich mich gerade, weiß jedoch nicht genau, woher ich - bei veränderlichem Arrayinhalt - weiß, wie groß die Häppchen denn maximal sein dürfen?
Naja, du kannst dir ja einfach immer 10000 Elemente (Floats, sagtest du ja) schnappen und diese dann in die Datei schreiben. Da sollte jeder halbwegs zeitgemäß ausgestattete Rechner RAM-technisch locker mit klarkommen. Ggf durch Ausprobieren schauen, wo der optimale Kompromiss zwischen Speicherverbrauch und `write()`-Zugriffen liegt. Wobei du da natürlich beachten musst, ob das Programm nur auf deiner Kiste läuft oder auch noch anderswo (wo entsprechend andere technische Gegebenheiten herrschen) eingesetzt wird. Ich finde die besagten 10000 nicht verkehrt. Evtl möchtest du in deiner Schreibmethode einfach einen Parameter mit Standardwert anlegen, den der Benutzer bei Bedarf verändern kann.
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 14:56
von SVPAM
Naja, du kannst dir ja einfach 10000 Elemente (Floats, sagtest du ja) schnappen und diese dann in die Datei schreiben.
Ja, so werde ich es machen. Hatte mit meinen Kollegen hier zwar an 10^5 gedacht, aber das ist ja dann ausprobierbar, wie Du selber schreibst.
Danke!
Ich denke, das Thema ist damit beantwortet.
Eure "post-Geschwindigkeit" ist beeindruckend
Gruß
SVPAM
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 14:58
von EyDu
SVPAM hat geschrieben:Ja, das habe ich gleich anfangs ausprobiert, jedoch keinen Geschwindigkeitsgewinn erzielen können.
Ich kann damit locker 10 Mio. Elemente speichern, ohne dass ich überhaupt merke, dass es eine Verzögerung gibt.
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 15:06
von snafu
Ich hab jetzt auch etwas doof gerechnet (Größenverhältnisse nicht wirklich beachtet). 10 Mio sind wahrscheinlich wirklich sinnvoller... ^^
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 15:19
von snafu
Vielleicht interessiert dich auch
sys.getsizeof(), welches den Speicherverbrauch für ein Python-Objekt angibt. Laut Doku funktioniert das mindestens für Pythons Builtin-Typen zuverlässig. Bei mir belegt ein leerer Python-String 37 Bytes. Jedes Zeichen im String belegt ein weiteres Byte. Könnte zur Orientierung ganz nützlich sein.
//edit: Dann aber wohl eher bezogen auf das Array. Beim String kann man ja einfach die durchschnittliche Länge der Floats nehmen. Grundsätzlich ist das aber viel Hokuspokus, der wahrscheinlich nicht nötig sein wird. Stumpfes Ausprobieren ist hier sicher der bessere Weg...

Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 15:31
von SVPAM
``numpy.save`` ist dir bekannt? ... Ich kann damit locker 10 Mio. Elemente speichern
Habe es gerade ausprobiert und es tut wirklich in <1sec:
Code: Alles auswählen
b=numpy.array(1e9)
outfile = 'numpysave.dat'
numpy.save(outfile, b)
Muss mir noch anschauen, was es mit diesem .npy Format auf sich hat und wie ich das für die nachgelagerte Auswertung nutzen kann. Habe schon
http://docs.scipy.org/doc/numpy/referen ... .save.html gefunden.
Für alle, die so etwas auch interessant finden:
führt zum Fehler:
"a = ["0"] * 1000000000
Memory Error"
wohingegen
problemlos angenommen und in <1sec verarbeitet wird.
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 15:50
von BlackJack
@SVPAM: Dir ist aber schon klar, dass ``numpy.array(1e9)`` kein Array erzeugt, sondern *einen* Skalarwert!?
Code: Alles auswählen
In [248]: a = np.array(1e9)
In [249]: a
Out[249]: array(1000000000.0)
In [250]: len(a)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/bj/<ipython console> in <module>()
TypeError: len() of unsized object
In [251]: a.ndim
Out[251]: 0
Re: Array speichern - Geschwindigkeitsproblem mit f.write()
Verfasst: Mittwoch 18. April 2012, 16:00
von SVPAM
dass ``numpy.array(1e9)`` kein Array erzeugt, sondern *einen* Skalarwert!?
Ok ... wieder etwas dazugelernt.