it-swarm.com.de

In-Memory-Größe einer Python-Struktur

Gibt es eine Referenz für die Speichergröße der Python-Datenstruktur auf 32- und 64-Bit-Plattformen?

Wenn nicht, wäre es schön, es auf SO zu haben. Je umfassender desto besser! Wie viele Bytes werden also von den folgenden Python-Strukturen verwendet (je nach len und ggf. Inhaltstyp)?

  • int
  • float
  • referenz
  • str
  • unicode-Zeichenfolge
  • Tuple
  • list
  • dict
  • set
  • array.array
  • numpy.array
  • deque
  • klassenobjekt im neuen Stil
  • klassenobjekt im alten Stil
  • ... und alles was ich vergesse!

(Für Container, die nur Verweise auf andere Objekte enthalten, möchten wir natürlich nicht die Größe des Objekts selbst zählen, da es möglicherweise gemeinsam genutzt wird.)

Gibt es außerdem eine Möglichkeit, den zur Laufzeit von einem Objekt belegten Speicher (rekursiv oder nicht) abzurufen?

102
LeMiz

Die Empfehlung von eine frühere Frage war dazu, sys.getsizeof () zu verwenden und zitierte:

>>> import sys
>>> x = 2
>>> sys.getsizeof(x)
14
>>> sys.getsizeof(sys.getsizeof)
32
>>> sys.getsizeof('this')
38
>>> sys.getsizeof('this also')
48

Sie könnten diesen Ansatz wählen:

>>> 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 (Standardeinstellung: 23. Oktober 2015, 19:19:21) [GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-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
125
hughdbrown

Ich habe fröhlich pympler für solche Aufgaben verwendet. Es ist mit vielen Python-Versionen kompatibel - insbesondere das Modul asizeof geht auf 2.2 zurück!

Wenn Sie beispielsweise das Beispiel von hughdbrown verwenden, jedoch am Anfang from pympler import asizeof und am Ende print asizeof.asizeof(v), sehe ich (System Python 2.5 unter MacOSX 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

Natürlich gibt es hier eine Annäherung, aber ich habe es als sehr nützlich für die Analyse des Fußabdrucks und das Tuning angesehen.

33
Alex Martelli

Diese Antworten sammeln alle Informationen zur flachen Größe. Ich vermute, dass Besucher dieser Frage hier enden werden, um die Frage zu beantworten: "Wie groß ist dieses komplexe Objekt im Gedächtnis?"

Hier gibt es eine großartige Antwort: https://goshippo.com/blog/measure-real-size-any-python-object/

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

So benutzt:

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 mehr über das Speichermodell von Python erfahren möchten, finden Sie hier einen großartigen Artikel, der als Teil einer längeren Erklärung ein ähnliches Codefragment für die Gesamtgröße enthält: https://code.tutsplus.com/tutorials/understand- Wie-viel-Speicher-Ihre-Python-Objekte-Verwendung - cms-25609

22
Kobold

Sie können auch guppy module verwenden.

>>> 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
7
Omid Raha

Versuchen Sie den Speicherprofiler . Speicherprofiler

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
7
Tampa

Wenn Sie die eingebaute Funktion dir ([object]) verwenden, können Sie die eingebaute Funktion sizeof verwenden.

>>> a = -1
>>> a.__sizeof__()
24
0
hello_god