In-Memory-Größe einer Struktur Python
-
19-09-2019 - |
Frage
Gibt es eine Referenz für die Speichergröße von Python-Daten stucture auf 32- und 64-Bit-Plattformen?
Wenn nicht, wäre dies schön es auf SO zu haben. Je mehr Anspruch auf Vollständigkeit, desto besser! So, wie viele Bytes werden durch die folgenden Python-Strukturen verwendet (je nach len
und dem Inhaltstyp, wenn relevant)?
-
int
-
float
- Referenz
-
str
- Unicode-String
-
tuple
-
list
-
dict
-
set
-
array.array
-
numpy.array
-
deque
- new-Style-Klassen-Objekt
- old-style-Klassen-Objekt
- ... und alles, was ich bin zu vergessen!
(für Container, die auf andere Objekte nur Verweise zu halten, wollen wir natürlich nicht die Größe des Elements zählen selbst, da sie gemeinsam genutzt werden könnte.)
Darüber hinaus gibt es eine Möglichkeit, den Speicher durch ein Objekt zur Laufzeit (rekursiv oder nicht) verwendet werden?
Lösung
Die Empfehlung von eine frühere Frage auf diese war sys.getsizeof () zu verwenden, unter Angabe :
>>> import sys
>>> x = 2
>>> sys.getsizeof(x)
14
>>> sys.getsizeof(sys.getsizeof)
32
>>> sys.getsizeof('this')
38
>>> sys.getsizeof('this also')
48
Sie können diesen Ansatz:
>>> import sys
>>> import decimal
>>>
>>> d = {
... "int": 0,
... "float": 0.0,
... "dict": dict(),
... "set": set(),
... "tuple": tuple(),
... "list": list(),
... "str": "a",
... "unicode": u"a",
... "decimal": decimal.Decimal(0),
... "object": object(),
... }
>>> for k, v in sorted(d.iteritems()):
... print k, sys.getsizeof(v)
...
decimal 40
dict 140
float 16
int 12
list 36
object 8
set 116
str 25
tuple 28
unicode 28
2012-09-30
Python 2.7 (Linux, 32-Bit):
decimal 36
dict 136
float 16
int 12
list 32
object 8
set 112
str 22
tuple 24
unicode 32
Python 3.3 (Linux, 32-bit)
decimal 52
dict 144
float 16
int 14
list 32
object 8
set 112
str 26
tuple 24
unicode 26
2016.08.01
OSX, Python 2.7.10 (Standard, 23. Oktober 2015, 19.19.21) [GCC 4.2.1 kompatiblen Apple LLVM 7.0.0 (Klirren-700.0.59.5)] auf darwin
decimal 80
dict 280
float 24
int 24
list 72
object 16
set 232
str 38
tuple 56
unicode 52
Andere Tipps
Ich habe gerne benutze pympler für solche Aufgaben. Es ist kompatibel mit vielen Versionen von Python - das asizeof
Modul insbesondere auf 2,2 zurückgeht
Zum Beispiel hughdbrown das Beispiel verwenden, aber mit from pympler import asizeof
am Anfang und print asizeof.asizeof(v)
am Ende, ich sehe (System Python 2.5 auf Mac OS X 10.5):
$ python pymp.py
set 120
unicode 32
tuple 32
int 16
decimal 152
float 16
list 40
object 0
dict 144
str 32
Offensichtlich gibt es einige Annäherung hier, aber ich habe es sehr nützlich für Footprint-Analyse und Abstimmung gefunden.
Diese Antworten alle collect flache Größeninformationen. Ich vermute, dass die Besucher auf diese Frage wird aufzublicken hier am Ende die Frage zu beantworten: „Wie groß dieses komplexe Objekt im Speicher ist?“
Es gibt eine große Antwort hier: https://goshippo.com / Blog / Maß-real-size-any-python-Objekt /
Die Pointe:
import sys
def get_size(obj, seen=None):
"""Recursively finds size of objects"""
size = sys.getsizeof(obj)
if seen is None:
seen = set()
obj_id = id(obj)
if obj_id in seen:
return 0
# Important mark as seen *before* entering recursion to gracefully handle
# self-referential objects
seen.add(obj_id)
if isinstance(obj, dict):
size += sum([get_size(v, seen) for v in obj.values()])
size += sum([get_size(k, seen) for k in obj.keys()])
elif hasattr(obj, '__dict__'):
size += get_size(obj.__dict__, seen)
elif hasattr(obj, '__iter__') and not isinstance(obj, (str, bytes, bytearray)):
size += sum([get_size(i, seen) for i in obj])
return size
Gebrauchte etwa so:
In [1]: get_size(1)
Out[1]: 24
In [2]: get_size([1])
Out[2]: 104
In [3]: get_size([[1]])
Out[3]: 184
Wenn Sie Speichermodell Python wissen wollen, tiefer, es ist ein großer Artikel hier, die eine ähnliche „Gesamtgröße“ Snippet hat den Code als Teil einer längeren Erklärung: https://code.tutsplus.com/tutorials/understand-how-much-memory -Ihr-python-Objekte-use - cms-25609
Versuchen Speicher-Profiler. Speicher-Profiler
Line # Mem usage Increment Line Contents
==============================================
3 @profile
4 5.97 MB 0.00 MB def my_func():
5 13.61 MB 7.64 MB a = [1] * (10 ** 6)
6 166.20 MB 152.59 MB b = [2] * (2 * 10 ** 7)
7 13.61 MB -152.59 MB del b
8 13.61 MB 0.00 MB return a
Sie können auch verwenden Guppy Modul.
>>> from guppy import hpy; hp=hpy()
>>> hp.heap()
Partition of a set of 25853 objects. Total size = 3320992 bytes.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 11731 45 929072 28 929072 28 str
1 5832 23 469760 14 1398832 42 tuple
2 324 1 277728 8 1676560 50 dict (no owner)
3 70 0 216976 7 1893536 57 dict of module
4 199 1 210856 6 2104392 63 dict of type
5 1627 6 208256 6 2312648 70 types.CodeType
6 1592 6 191040 6 2503688 75 function
7 199 1 177008 5 2680696 81 type
8 124 0 135328 4 2816024 85 dict of class
9 1045 4 83600 3 2899624 87 __builtin__.wrapper_descriptor
<90 more rows. Type e.g. '_.more' to view.>
Und:
>>> hp.iso(1, [1], "1", (1,), {1:1}, None)
Partition of a set of 6 objects. Total size = 560 bytes.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 1 17 280 50 280 50 dict (no owner)
1 1 17 136 24 416 74 list
2 1 17 64 11 480 86 tuple
3 1 17 40 7 520 93 str
4 1 17 24 4 544 97 int
5 1 17 16 3 560 100 types.NoneType
Wenn Sie das dir ([object]) eingebaute Funktion, können Sie die sizeof integrierte Funktion.
>>> a = -1
>>> a.__sizeof__()
24