Speicherplatz json

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.
Antworten
tschaka81
User
Beiträge: 31
Registriert: Donnerstag 24. Januar 2019, 08:15

Hallo an alle,

ich beschäftige mich gerade damit Daten aus Python über einen Restful Webserver auf einer Webpage darzustellen. Das klappt auch erstmal alles so.
Derzeit bin ich dabei einen Contourplot zu bauen. Die einlaufenden Daten können mitunter sehr groß sein. (mehrere 100MB). An und für sich ist das kein Problem. Aber die Schnittstelle Python HTML macht mir ein wenig sorgen:

Bisher hatte ich immer die Daten aus Python in einen JSON -String umgewandelt. und dann die Daten über den Restful Webserver an die verschiedenen Seiten verteilt. Jetzt hatte ich mir mal folgendes angeschaut:

Ich habe eine 2d-liste
Wenn ich von dieser einen getsizeof mache bekomme ich als Antwort 864 bytes
jetzt kommen folgende versuche:
json.dumps -> 2.003.337 bytes
json.dumps mit zlib compression -> 867.877 bytes
msgpack -> 816.504 bytes

Also im wesentlichen wird meine liste im Speicher vertausendfacht.

Meine 2d-Liste besteht derzeit aus positiven Integer Werten. Wie kann ich den Speicherverbrauch reduzieren beim Übertragen der Daten?

Schöne Grüße

Markus
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

Ich verstehe gerade den Zusammenhang nicht.
Was bewertest du denn bei "json.dumps()"? Die Länge des Resultats? Was hat die mit der Speicherbelegung zu tun?
Das klingt ein bisschen wie Äpfel und Birnen.

Und warum hast du ein Speicherproblem?
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

`getsizeof` liefert nicht die ganze Speicherbelegung, sondern nur die der obersten Liste.
tschaka81
User
Beiträge: 31
Registriert: Donnerstag 24. Januar 2019, 08:15

Hallo sparrow,

soweit ich weiß (und ggf. irre ich hier) gibt getsizeof den Speicher an, welcher dieses Objekt derzeit belegt. Würde ich das Objekt so abspeichern, dann wäre das Objekt auf der Festplatte ebenso groß.

Aber ich glaube du hast mich da auf etwas gestoßen: Denn nach ein wenig Recherche kam für mich jetzt heraus, dass das obige nicht für eine Liste in Python funktioniert. Somit vergleiche ich tatsächlich Äpfel mit Birnen.

D.h. für mich für mein kleines Beispiel von knapp 1MB bin ich schon optimiert. Später habe ich knapp 100x mehr Daten.
D.h. ich muss vor dem Senden noch optimieren und zusammenfassen.

Manchmal sieht man den Wald vor lauter Bäumen nicht. Danke für das "vor den Kopf schlagen" :)
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

Nee, da verstehst du de getsizeof falsch.
Das kann etwas über die Größe im Speicher aussagen, ist aber etwas speziell. Wenn du wissen willst, wie groß etwas auf die Platte geschrieben wird, hat das nichts mit dem Speicher zu tun:

Code: Alles auswählen

>>> import sys
>>> a = 5
>>> sys.getsizeof(a)
14
>>> a = 1234567
>>> sys.getsizeof(a)
16
Ich würde sagen, "5" ist auf die Platte geschrieben ziemlich genau 1 Byte, 1234567 ziemlich genau 7.
Vorausgesetzt es wird 1 Zeichen = 1 Byte geschrieben, die Zahl also in eine Zeichenkette gewandelt.

Schreib doch mal das Resultat des Dumps in eine Datei, schau sie dir an und schau dir mal die Größe auf der Platte an.
tschaka81
User
Beiträge: 31
Registriert: Donnerstag 24. Januar 2019, 08:15

sparrow hat geschrieben: Montag 13. Januar 2020, 11:14 Nee, da verstehst du de getsizeof falsch.
Das kann etwas über die Größe im Speicher aussagen, ist aber etwas speziell. Wenn du wissen willst, wie groß etwas auf die Platte geschrieben wird, hat das nichts mit dem Speicher zu tun:

Code: Alles auswählen

>>> import sys
>>> a = 5
>>> sys.getsizeof(a)
14
>>> a = 1234567
>>> sys.getsizeof(a)
16
Ich würde sagen, "5" ist auf die Platte geschrieben ziemlich genau 1 Byte, 1234567 ziemlich genau 7.
Vorausgesetzt es wird 1 Zeichen = 1 Byte geschrieben.

Schreib doch mal das Resultat des Dumps in eine Datei, schau sie dir an und schau dir mal die Größe auf der Platte an.
Mhh für dumps ist es genau das gleiche, wie es bei getsizeof herauskommt. Das liegt aber daran, (glaube ich), dass ein ein einzelnes String Zeichen zufälligerweise genau 1 Byte hat. Daher hatte mich das auch verwirrt :)
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

@tschaka81: dass ich Recht habe, aber konsequent ignoriert werde, und statt dessen wild herumspekuliert wird, kannst Du einfach selbst testen:

Code: Alles auswählen

import sys
a = [1] * 1000
print(sys.getsizeof(a))
# 8072
b = [a]
print(sys.getsizeof(b))
# 80
`getsizeof` ist also absolut nutzlos.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1239
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Meine 2d-Liste besteht derzeit aus positiven Integer Werten. Wie kann ich den Speicherverbrauch reduzieren beim Übertragen der Daten?
In dem du die Daten binär überträgst, anstatt json zu verwenden.
Der Unterschied ist halt, dass bei binären Daten der Datentyp und die Datenstruktur bekannt sein müssen.

Code: Alles auswählen

# Sender
shape = (10, 10)
dtype = np.uint16
daten = np.random.randint(0, 65536, size=shape, dtype=dtype)

daten_bytes = bytes(daten)
# oder
daten_bytes = daten.tobytes()

# Empfänger
shape = (10, 10)
dtype = np.uint16
array = np.frombuffer(daten_bytes, dtype=dtype).reshape(shape)
Denk mal einfach drüber nach, wieso die anderen Formate wie z.B. xml (html), json, yaml, ini alle grundsätzlich größer sind, als die enthaltenen Daten.
Vorteil der genannten Formate ist, dass quasi so ziemlich jede Sprache diese Formate sehr einfach verarbeiten kann.
Bei Binärdaten muss man halt wissen was man macht oder sich auf ein Framework verlassen, dass einem die Arbeit abnimmt.

Wenn du msgpack verwendest, hast du schonmal eine MessageQueue mit wenig Overhead.
Rein theoretisch könntest du die Objekte auch mit Pickle serialisieren und dann senden.
Pickle hat auch nicht so viel Overhead wie die anderen menschenlesbare Formate.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Pickle und Web vertragen sich nicht, weil man damit vollen Remote-Zugriff auf den Server hat.
Antworten