Große Liste mit compress komprimieren ... ???

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
CapJo
User
Beiträge: 26
Registriert: Donnerstag 27. April 2006, 13:17

Nach dem splitten hab ich ja eine Liste mit vielen Strings. Ich will jedoch den Wert des String und dann wär wohl ein int() nötig.

Code: Alles auswählen

import time, cPickle, zlib
#-------------------------------------------------------------------------------
integers = range(4000000)

#Einmal durchlaufen für "gleiche" Bedingungen
for i in integers:
    pass
#-------------------------------------------------------------------------------
start = time.time()

string_join = ",".join([str(item) for item in integers]) 
  
integer_list = string_join.split(",")

##for string in string_join.split(","):
##    integer_list.append(int(string))
    
map(int, integer_list)
    
print integer_list[-1]

end = time.time()

print "Time of join / split: " + str(end - start)
print "Size of String resulting String join / split: " + str(len(string_join))
print "Compressed Size: " + str(len(zlib.compress(string_join))) 

#-------------------------------------------------------------------------------

start = time.time()

string_pickle = cPickle.dumps(integers)
integer_list_pickle = cPickle.loads(string_pickle)

print integer_list_pickle[-1]

end = time.time()

print "Time of cPickle: " + str(end - start)
print "Size of String resulting String cPickle: " + str(len(string_pickle))
print "Compressed Size: " + str(len(zlib.compress(string_pickle))) 
3999999
Time of join / split: 17.2139999866
Size of String resulting String join / split: 30888889
Compressed Size: 8443383
3999999
Time of cPickle: 9.51300001144
Size of String resulting String cPickle: 38888896
Compressed Size: 8880297

cPickle scheint schneller zu sein, als join + split + int.
Zuletzt geändert von CapJo am Montag 19. Juni 2006, 15:24, insgesamt 1-mal geändert.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hast recht. Hätte ich nicht gedacht!
Naja wobei cPickle ja auch in C geschrieben ist. Gegenüber dem normalen Pickle ist die Join-Split Variante aber besser...

Im übrigen kannst du es mit cPickle.HIGHEST_PROTOCOL noch eine ganze Ecke kleiner haben! Außerdem gehts dann noch ein wenig schneller...
Siehe: http://docs.python.org/lib/node64.html

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

import time, cPickle, pickle

integers = range(1000000)



print "Time of join / split"
start = time.time()

string_join = ",".join([str(item) for item in integers])
integer_list = [int(i) for i in string_join.split(",")]

print "%.2fSec" % (time.time() - start)
print "Size:", len(string_join)
print "-"*79



print "cPickle normal"
start = time.time()

string_pickle = cPickle.dumps(integers)
integer_list_pickle = cPickle.loads(string_pickle)

print "%.2fSec" % (time.time() - start)
print "Size:", len(string_pickle)
print "-"*79



print "cPickle HIGHEST_PROTOCOL:"
start = time.time()

string_pickle = cPickle.dumps(integers, cPickle.HIGHEST_PROTOCOL)
integer_list_pickle = cPickle.loads(string_pickle)

print "%.2fSec" % (time.time() - start)
print "Size:", len(string_pickle)
print "-"*79



print "normal pickle:"
start = time.time()

string_pickle = pickle.dumps(integers, pickle.HIGHEST_PROTOCOL)
integer_list_pickle = pickle.loads(string_pickle)

print "%.2fSec" % (time.time() - start)
print "Size:", len(string_pickle)
Ausgabe:
Time of join / split
2.92Sec
Size: 6888889
-------------------------------------------------------------------------------
cPickle normal
1.56Sec
Size: 8888896
-------------------------------------------------------------------------------
cPickle HIGHEST_PROTOCOL:
0.36Sec
Size: 4870678
-------------------------------------------------------------------------------
normal pickle:
8.42Sec
Size: 4870678

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
CapJo
User
Beiträge: 26
Registriert: Donnerstag 27. April 2006, 13:17

Wo wir gerade bei Performance sind:

Ich hab getestet wie groß der Unterschied zwischen einer For-Schleife und der map-Funktion ist.

Bei vielen Objekten ist es lohnenswert die map-Funktion zu benutzen. Sie ist aber nicht so flexibel und sicher nicht überall einsetzbar.

Code: Alles auswählen

import time

integers = range(10000000)
#-------------------------------------------------------------------------------
start = time.time()
map(abs, integers)
end = time.time()

print "Time of map: " + str(end - start)
#-------------------------------------------------------------------------------
start = time.time()
list = [abs(x) for x in integers]
end = time.time()

print "Time of for-loop with new list: " + str(end - start)
#-------------------------------------------------------------------------------
start = time.time()
for x in integers:
    abs(x)
    
end = time.time()

print "Time of for-loop without new list: " + str(end - start)
Time of map: 1.64199995995
Time of for-loop with new list: 6.83899998665
Time of for-loop without new list: 2.99499988556
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hm, komisch der Unterschied zwischen

Code: Alles auswählen

integer_list = [int(i) for i in string_join.split(",")]
und

Code: Alles auswählen

map(int, string_join.split(","))
ist bei mir nicht so groß.

Aber immerhin! Ich dachte eigentlich das LCs schnell sind oder zumindest gleich schnell wie eine normale for-Schleife...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
CapJo
User
Beiträge: 26
Registriert: Donnerstag 27. April 2006, 13:17

Der Geschwindigkeitsvorteil dürfte wieder mal darin liegen, dass die map()-Funktion in C implementiert ist.

Der Geschwindigkeitsvorteil fällt jedoch umso geringer aus desto länger die Funktion dauert ist die man wiederholt aufruft.

Ich hab es mit der abs()-Funktion getestet, da diese relativ schnell sein sollte.
BlackJack

Wäre es nicht am schnellsten wenn Du die Daten einfach entweder direkt aus dem ctypes Array abspeicherst (muss wohl in C geschehen) oder in eine Zeichenkette wandelst und die dann abspeicherst? Das wäre dann nur ein einfaches umkopieren und keine Umwandlung in ein anderes Format. Zum Arbeiten mit den Werten könnte man dann das `array` Modul oder vielleicht auch `numpy` benutzen.
CapJo
User
Beiträge: 26
Registriert: Donnerstag 27. April 2006, 13:17

@BlackJack

Dein Vorschlag würd sicherlich auch gehen, aber wir wollten da nicht zu viel Aufwand treiben.

Mit unseren Optimierungen konnten wir die Laufzeit von 2,5 Minuten auf 7 Sekunden senken und durch die Kompression hat die aktuell aufgezeichnete Datei nur noch 11 Kbyte anstatt von 5 Mbyte.

Ich muss dazu noch sagen, dass in der ursprünglichen Fassung viele Sachen mehrmals unnötig durchlaufen wurden.
Antworten