Python'da bir nesnenin boyutunu nasıl belirlerim?


683

Python bir dize, tamsayı, vb gibi nesnelerin boyutunu almak nasıl bilmek istiyorum.

İlgili soru: Python listesinde (grup) öğe başına kaç bayt var?

Değerin boyutunu belirten boyut alanları içeren bir XML dosyası kullanıyorum. Bu XML'i ayrıştırmalı ve kodumu yapmalıyım. Belirli bir alanın değerini değiştirmek istediğimde, o değerin boyut alanını kontrol edeceğim. Burada girmek için gong yeni değeri XML ile aynı boyutta olup olmadığını karşılaştırmak istiyorum. Yeni değerin boyutunu kontrol etmem gerekiyor. Bir dize durumunda uzunluğu olduğunu söyleyebilirim. Ama int, şamandıra vb. Durumunda kafam karıştı.

Yanıtlar:


664

Sadece modülde tanımlanan sys.getsizeof işlevini kullanın sys.

sys.getsizeof(object[, default]):

Bir nesnenin boyutunu bayt olarak döndürür. Nesne, herhangi bir nesne türü olabilir. Tüm yerleşik nesneler doğru sonuçları döndürür, ancak uygulamaya özgü olduğu için bunun üçüncü taraf uzantıları için geçerli olması gerekmez.

defaultBağımsız değişken nesne türü boyutunu almak için bir araç sağlamaz ve sebep olursa döndürülür bir değer için imkan sağlar TypeError.

getsizeofnesnenin __sizeof__yöntemini çağırır ve nesne çöp toplayıcı tarafından yönetiliyorsa ek bir çöp toplayıcı ek yükü ekler.

Python 3.0'da kullanım örneği:

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

Python <2.6 içindeyseniz ve sahip sys.getsizeofdeğilseniz, bu kapsamlı modülü kullanabilirsiniz . Yine de hiç kullanmadım.


182
O vb listelerinde iç içe nesneler veya iç içe dicts veya dicts için geçerli olmaz reddi için ekleyiniz
JohnnyM

8
@ChaimG çünkü her nesne sadece 32 bayt kullanıyor !! Gerisi diğer nesnelere referanstır. Başvurulan nesneleri hesaba katmak istiyorsanız __sizeof__, sınıfınız için bir yöntem tanımlamanız gerekir. Yerleşik dictpiton sınıfının türündeki nesne kullanırken doğru sonucu neden olduğunu, bunu tanımlıyor dict.
nosklo

19
Bu çalışmadaki feragatname ve istisnalar neredeyse tüm kullanımları getsizeofkutudan çok az değerde olan durumları kapsar .
Robino

7
tamsayı 2 neden 24 baytta saklanır?
Saher Ahwal

4
@SaherAhwal sadece bir tamsayı değil, yöntemlerle, özniteliklerle, adreslerle dolu bir nesne ...
nosklo

371

Python'da bir nesnenin boyutunu nasıl belirlerim?

"Sadece sys.getsizeof kullanın" yanıtı tam bir yanıt değildir.

Bu cevap yapar özellikle yerleşiğine için çalışma doğrudan nesneleri, ancak bu nesneler içerebilir neyi dikkate almaz, bu tür özel nesneler, küpe, listeler, dicts ve batarken ne tür içerir. Birbirlerinin örneklerini, sayıları, dizeleri ve diğer nesneleri içerebilirler.

Daha Eksiksiz Bir Yanıt

Anaconda dağıtımından 64 bit Python 3.6 kullanarak, sys.getsizeof ile, aşağıdaki nesnelerin minimum boyutunu belirledim ve setlerin ve diklerin, önceden belirlenmiş bir miktarın sonuna kadar ( dilin uygulamasına göre değişir):

Python 3:

Empty
Bytes  type        scaling notes
28     int         +4 bytes about every 30 powers of 2
37     bytes       +1 byte per additional byte
49     str         +1-4 per additional character (depending on max width)
48     tuple       +8 per additional item
64     list        +8 for each additional
224    set         5th increases to 736; 21nd, 2272; 85th, 8416; 341, 32992
240    dict        6th increases to 368; 22nd, 1184; 43rd, 2280; 86th, 4704; 171st, 9320
136    func def    does not include default args and other attrs
1056   class def   no slots 
56     class inst  has a __dict__ attr, same scaling as dict above
888    class def   with slots
16     __slots__   seems to store in mutable tuple-like structure
                   first slot grows to 48, and so on.

Bunu nasıl yorumluyorsun? İçinde 10 öğe bulunan bir setin olduğunu söyle. Her bir öğenin her biri 100 bayt ise, tüm veri yapısı ne kadar büyüktür? Set 736 kendisidir çünkü bir kez 736 bayta kadar boyutlandırmıştır. Sonra öğelerin boyutunu eklersiniz, bu toplamda 1736 bayttır

Fonksiyon ve sınıf tanımları için bazı uyarılar:

Her sınıf tanımının, __dict__sınıf izinleri için bir proxy (48 bayt) yapısına sahip olduğunu unutmayın. Her yuva, propertysınıf tanımında bir tanımlayıcıya (a gibi ) sahiptir.

Oluklu örnekler ilk öğelerinde 48 bayt ile başlar ve her biri ek 8 artar. Yalnızca boş oluklu nesneler 16 bayt içerir ve veri içermeyen bir örnek çok az mantıklıdır.

Ayrıca, her işlev tanımının kod nesneleri, belki docstrings ve diğer olası öznitelikleri, hatta bir __dict__.

Ayrıca sys.getsizeof(), nesnenin çöp toplama yükünü içeren marjinal alan kullanımını dokümanlardan aldığımız için kullandığımızı da unutmayın :

getsizeof () nesnenin __sizeof__yöntemini çağırır ve nesne çöp toplayıcı tarafından yönetiliyorsa ek bir çöp toplayıcı ek yükü ekler.

Ayrıca, listelerin yeniden boyutlandırılmasının (örneğin, bunlara tekrar tekrar eklenerek), kümelere ve diktelere benzer şekilde, alanı önceden konumlandırmasına neden olduğunu unutmayın. Gönderen listobj.c kaynak kodu :

    /* This over-allocates proportional to the list size, making room
     * for additional growth.  The over-allocation is mild, but is
     * enough to give linear-time amortized behavior over a long
     * sequence of appends() in the presence of a poorly-performing
     * system realloc().
     * The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
     * Note: new_allocated won't overflow because the largest possible value
     *       is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t.
     */
    new_allocated = (size_t)newsize + (newsize >> 3) + (newsize < 9 ? 3 : 6);

Tarihsel veri

Python 2.7 analizi, guppy.hpyve ile onaylanmıştır sys.getsizeof:

Bytes  type        empty + scaling notes
24     int         NA
28     long        NA
37     str         + 1 byte per additional character
52     unicode     + 4 bytes per additional character
56     tuple       + 8 bytes per additional item
72     list        + 32 for first, 8 for each additional
232    set         sixth item increases to 744; 22nd, 2280; 86th, 8424
280    dict        sixth item increases to 1048; 22nd, 3352; 86th, 12568 *
120    func def    does not include default args and other attrs
64     class inst  has a __dict__ attr, same scaling as dict above
16     __slots__   class with slots has no dict, seems to store in 
                   mutable tuple-like structure.
904    class def   has a proxy __dict__ structure for class attrs
104    old class   makes sense, less stuff, has real dict though.

Sözlüklerin ( ancak kümeler değil ) Python 3.6'da daha kompakt bir temsili olduğunu unutmayın

Ek bir öğe başına 8 baytlık 64 bitlik bir makinede çok anlamlı olduğunu düşünüyorum. Bu 8 bayt, bellekteki öğenin bulunduğu yeri gösterir. 4 bayt Python 2'de unicode için sabit genişliktir, doğru hatırlarsam, ancak Python 3'te str, karakterlerin maksimum genişliğine eşit bir unicode genişliğine dönüşür.

(Ve slotlar hakkında daha fazla bilgi için bu cevaba bakınız )

Daha Eksiksiz Bir İşlev

Listeler, tuples, kümeler, diktler, obj.__dict__'ler ve obj.__slots__henüz aklınıza gelmemiş olabilecek diğer şeyleri araştıran bir fonksiyon istiyoruz .

gc.get_referentsBu aramaya güvenmek istiyoruz çünkü C düzeyinde çalışıyor (çok hızlı yapıyor). Dezavantajı, get_referents'ın gereksiz üyeleri döndürebilmesidir, bu nedenle iki kez saymadığımızdan emin olmamız gerekir.

Sınıflar, modüller ve işlevler tek tonludur - bellekte bir kez bulunurlar. Boyutlarıyla o kadar ilgilenmiyoruz, çünkü onlar hakkında yapabileceğimiz çok şey yok - bunlar programın bir parçası. Bu nedenle, referans gösterildikleri takdirde onları saymaktan kaçınacağız.

Kara liste türlerini kullanacağız, bu nedenle tüm programı boyut sayımımıza dahil etmiyoruz.

import sys
from types import ModuleType, FunctionType
from gc import get_referents

# Custom objects know their class.
# Function objects seem to know way too much, including modules.
# Exclude modules as well.
BLACKLIST = type, ModuleType, FunctionType


def getsize(obj):
    """sum size of object & members."""
    if isinstance(obj, BLACKLIST):
        raise TypeError('getsize() does not take argument of type: '+ str(type(obj)))
    seen_ids = set()
    size = 0
    objects = [obj]
    while objects:
        need_referents = []
        for obj in objects:
            if not isinstance(obj, BLACKLIST) and id(obj) not in seen_ids:
                seen_ids.add(id(obj))
                size += sys.getsizeof(obj)
                need_referents.append(obj)
        objects = get_referents(*need_referents)
    return size

Bunu aşağıdaki beyaz listeye eklenmiş işlevle karşılaştırmak için, çoğu nesne çöp toplama amacıyla kendilerini nasıl geçeceğini bilir (bu, belirli nesnelerin belleğinde ne kadar pahalı olduğunu bilmek istediğimizde yaklaşık olarak aradığımız şeydir. gc.get_referents.) Ancak, bu önlem, dikkatli olmazsak, kapsamda düşündüğümüzden çok daha geniş olacaktır.

Örneğin, işlevler oluşturuldukları modüller hakkında çok şey bilir.

Diğer bir kontrast noktası, sözlüklerde anahtar olan dizelerin çoğaltılmaması için genellikle stajyer olmasıdır. Denetleniyor id(key)da bize bir sonraki bölümde ne sayım çiftleri önlemek sağlayacaktır. Kara liste çözümü, dizeler olan sayma anahtarlarını tamamen atlar.

Beyaz Listeye Alınan Türler, Yinelemeli ziyaretçi (eski uygulama)

Bu türlerin çoğunu kendim kapsayacak şekilde, gc modülüne güvenmek yerine, çoğu yinelenen, koleksiyon modülündeki türler ve özel türler (oluklu ve diğer) dahil olmak üzere çoğu Python nesnesinin boyutunu tahmin etmeye çalışmak için bu özyinelemeli işlevi yazdım .

Bu tür bir işlev, bellek kullanımı için sayacağımız türler üzerinde çok daha hassas bir kontrol sağlar, ancak türleri dışarıda bırakma tehlikesi vardır:

import sys
from numbers import Number
from collections import Set, Mapping, deque

try: # Python 2
    zero_depth_bases = (basestring, Number, xrange, bytearray)
    iteritems = 'iteritems'
except NameError: # Python 3
    zero_depth_bases = (str, bytes, Number, range, bytearray)
    iteritems = 'items'

def getsize(obj_0):
    """Recursively iterate to sum size of object & members."""
    _seen_ids = set()
    def inner(obj):
        obj_id = id(obj)
        if obj_id in _seen_ids:
            return 0
        _seen_ids.add(obj_id)
        size = sys.getsizeof(obj)
        if isinstance(obj, zero_depth_bases):
            pass # bypass remaining control flow and return
        elif isinstance(obj, (tuple, list, Set, deque)):
            size += sum(inner(i) for i in obj)
        elif isinstance(obj, Mapping) or hasattr(obj, iteritems):
            size += sum(inner(k) + inner(v) for k, v in getattr(obj, iteritems)())
        # Check for custom object instances - may subclass above too
        if hasattr(obj, '__dict__'):
            size += inner(vars(obj))
        if hasattr(obj, '__slots__'): # can have __slots__ with __dict__
            size += sum(inner(getattr(obj, s)) for s in obj.__slots__ if hasattr(obj, s))
        return size
    return inner(obj_0)

Ve oldukça rahat bir şekilde test ettim (birimtest etmeliyim):

>>> getsize(['a', tuple('bcd'), Foo()])
344
>>> getsize(Foo())
16
>>> getsize(tuple('bcd'))
194
>>> getsize(['a', tuple('bcd'), Foo(), {'foo': 'bar', 'baz': 'bar'}])
752
>>> getsize({'foo': 'bar', 'baz': 'bar'})
400
>>> getsize({})
280
>>> getsize({'foo':'bar'})
360
>>> getsize('foo')
40
>>> class Bar():
...     def baz():
...         pass
>>> getsize(Bar())
352
>>> getsize(Bar().__dict__)
280
>>> sys.getsizeof(Bar())
72
>>> getsize(Bar.__dict__)
872
>>> sys.getsizeof(Bar.__dict__)
280

Bu uygulama, sınıf özniteliklerini ve işlev tanımlarını yıkar, çünkü tüm özniteliklerinin peşinden gitmeyiz, ancak işlem için yalnızca bir kez bellekte bulunması gerektiğinden, boyutları gerçekten çok fazla önemli değildir.


5
Bu cevabın CPython'a özgü olduğunu (Python'u Anaconda'dan aldığınız anlamına gelir) ekleyebilirsiniz
gerrit

1
CPython referans uygulamasıdır ve ben sadece aynı API sağlayan jython'un çevrimiçi belgelerini inceledim, bu yüzden API'leri uyguladıkları sürece bunun diğer uygulamalar üzerinde çalışacağına inanıyorum.
Aaron Hall

benim için maskelenmiş ve maskelenmemiş numpy dizileri için çalışmadı stackoverflow.com/q/58675479/2132157
GM

96

Pympler paketin asizeofmodülü yapabilirsiniz.

Aşağıdaki gibi kullanın:

from pympler import asizeof
asizeof.asizeof(my_object)

Bunun aksine sys.getsizeof, kendi oluşturduğunuz nesneler için çalışır . Hatta numpy ile çalışır.

>>> asizeof.asizeof(tuple('bcd'))
200
>>> asizeof.asizeof({'foo': 'bar', 'baz': 'bar'})
400
>>> asizeof.asizeof({})
280
>>> asizeof.asizeof({'foo':'bar'})
360
>>> asizeof.asizeof('foo')
40
>>> asizeof.asizeof(Bar())
352
>>> asizeof.asizeof(Bar().__dict__)
280
>>> A = rand(10)
>>> B = rand(10000)
>>> asizeof.asizeof(A)
176
>>> asizeof.asizeof(B)
80096

As bahsedildiği ,

Sınıflar, fonksiyonlar, yöntemler, modüller vb. Gibi nesnelerin (bayt) kod boyutu ayar seçeneği ile dahil edilebilir code=True.

Canlı verilerle ilgili başka bir görünüme ihtiyacınız varsa, Pympler's

modülü muppybir Python uygulamasının çevrimiçi izlenmesi için kullanılır ve modül Class Trackerseçilen Python nesnelerinin ömrünün çevrimdışı analizini sağlar.


bu işlev daha büyük nesneler için oldukça yavaştır. Kendi oluşturduğunuz nesneler için çalışan bir "hızlı" eşdeğeri var mı?
Shuklaswag

Henüz test etmedim, ancak org.apache.spark.util.SizeEstimatoralakalı olabilir
Shuklaswag

1
@Shuklaswag: kıvılcım kullanırsanız, iyi olabilir. Dönüşüm + Java tahmininin python'un yerleşik yöntemlerinden daha hızlı olduğunu düşünüyor musunuz ? Yoksa yanlış mı anladım?
serv-inc

3
pymplerİşlevlerin yürütülebilir kod boyutunu ve diğer callables ve kod nesnelerini dikkate alma yeteneklerine sahip olduğunu belirtmek gerekir .
mtraceur

Bir TypeErroristisna alıyorum: Özel nesnem "ağaç" değeri ile bazı alt nesne olduğunda "'NoneType' nesnesi çağrılabilir değil" None. Bunun için hızlı bir çözüm var mı?
James Hirschorn

81

Numpy diziler getsizeofiçin işe yaramaz - benim için her zaman bir nedenden dolayı 40 döndürür:

from pylab import *
from sys import getsizeof
A = rand(10)
B = rand(10000)

Sonra (ipython'da):

In [64]: getsizeof(A)
Out[64]: 40

In [65]: getsizeof(B)
Out[65]: 40

Ne mutlu ki:

In [66]: A.nbytes
Out[66]: 80

In [67]: B.nbytes
Out[67]: 80000

29
> Tüm yerleşik nesneler doğru sonuçları döndürür, ancak uygulamaya özgü olduğundan bunun üçüncü taraf uzantıları için geçerli olması gerekmez. docs.python.org/library/sys.html#sys.getsizeof
warvariuc

33
"Bir numpy dizisi ( docs.scipy.org/doc/numpy/reference/arrays.ndarray.html ) kullanıyorsanız, bellekteki boyutunu değerlendirmek için 'ndarray.nbytes' özelliğini kullanabilirsiniz." stackoverflow.com/a/15591157/556413
glarrain

17
40 bayt doğru olduğunu tahmin ediyorum, ancak getsizeof()sadece içerideki verilerin değil, nesnenin boyutunu (dizinin başlığı) verir. Python konteynerleri için de aynı sys.getsizeof([1,2,4]) == sys.getsizeof([1,123**456,4]) == 48durumdayken,sys.getsizeof(123**456) = 436
yota

3
getsizeof()Fonksiyonun beklenen değeri döndürmek için bir noktada değiştirildiği anlaşılıyor .
dshin

16

Python 3.8 (Q1 2019) sonuçlarının bazı değişecek sys.getsizeofgibi burada açıklanan Raymond Hettinger tarafından:

Python kapları 64 bitlik yapılarda 8 bayt daha küçüktür.

tuple ()  48 -> 40       
list  []  64 ->56
set()    224 -> 216
dict  {} 240 -> 232

Bu sorun 33597 ve Inada Naoki ( methane) 'nin Compact PyGC_Head ve PR 7043 etrafındaki çalışmalarından sonra gelir.

Bu fikir PyGC_Head boyutunu iki kelimeye indirir .

Şu anda, PyGC_Head üç kelime almaktadır ; gc_prev,, gc_nextve gc_refcnt.

  • gc_refcnt toplama sırasında, deneme silme işlemi için kullanılır.
  • gc_prev izleme ve izleme için kullanılır.

Bu nedenle, deneme silme işlemi sırasında izleme / izleme işleminden kaçınabilir gc_prevve gc_refcntaynı bellek alanını paylaşabilirsek.

Bkz. Taahhüt d5c875b :

Grubundan bir Py_ssize_tüye kaldırıldı PyGC_Head.
GC izlenen tüm nesnelerin (örn. Demet, liste, dikte) boyutu 4 veya 8 bayt olarak azaltılır.


14

Bu, şeyleri nasıl saymak istediğinize bağlı olarak göründüğünden daha karmaşık olabilir. Örneğin, bir ints listeniz varsa, ints referanslarını içeren listenin boyutunu istiyor musunuz? (örn. yalnızca liste, içerdiği içeriği değil) veya işaret edilen gerçek verileri dahil etmek istiyor musunuz, bu durumda yinelenen referanslarla uğraşmanız ve iki nesne referans içeriyorsa çift saymanın nasıl önleneceği aynı nesne.

İhtiyaçlarınızı karşılayıp karşılamadıklarını görmek için pysizer gibi python bellek profillerinden birine göz atmak isteyebilirsiniz .


10

Bu sorunla birçok kez karşılaştım, küçük bir işlev (@ aaron-hall'ın cevabından esinlenerek) yazdım ve sys.getsizeof'den beklediğim şeyi yapan testler yazdım:

https://github.com/bosswissam/pysize

Backstory ile ilgileniyorsanız, işte burada

EDIT: Kolay referans için aşağıdaki kodu ekleme. En güncel kodu görmek için lütfen github bağlantısını kontrol edin.

    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

7

İşte tüm değişkenlerin liste boyutlarına önceki cevaplara dayanarak yazdığım hızlı bir komut dosyası

for i in dir():
    print (i, sys.getsizeof(eval(i)) )

Yanlış değil, belirsiz. sys.getsizeof her zaman değer döndürür gereklidir, bu yüzden try..except ile performansı kaybetmeye gerek yoktur.
der_fenix

oh, bu iyi bir nokta ve bunu düşünmedim - şu anki formdaki kod sadece kronolojik olarak nasıl yazıldığını gösterir - önce numpy'yi (dolayısıyla nbytes) biliyordum, sonra daha genel bir çözüm aradım . _ / \ _
alexey

7

Nesnenin boyutu ile yakından ilişkili bir hesaplama türetmek için nesneyi serileştirebilirsiniz:

import pickle

## let o be the object, whose size you want to measure
size_estimate = len(pickle.dumps(o))

Turşu edilemeyen nesneleri ölçmek istiyorsanız (örneğin lambda ifadeleri nedeniyle) cloudpickle bir çözüm olabilir.


4

Bağlı (iç içe) nesnelerin boyutlarını dahil etmek istemiyorsanız sys.getsizeof () öğesini kullanın .

Bununla birlikte, listelerde, diktelerde, kümelerde, tupllerde iç içe geçmiş alt nesneleri saymak istiyorsanız ve genellikle BU, aradığınız şeydir - aşağıda gösterildiği gibi özyinelemeli derin sizeof () işlevini kullanın :

import sys
def sizeof(obj):
    size = sys.getsizeof(obj)
    if isinstance(obj, dict): return size + sum(map(sizeof, obj.keys())) + sum(map(sizeof, obj.values()))
    if isinstance(obj, (list, tuple, set, frozenset)): return size + sum(map(sizeof, obj))
    return size

Ayrıca bu fonksiyonu bulabilirsiniz şık birlikte diğer birçok yararlı tek gömlekleri ile, araç kutusu:

https://github.com/mwojnars/nifty/blob/master/util.py


3

Nesnenin tam boyutuna ihtiyacınız yoksa, ancak kabaca ne kadar büyük olduğunu bilmek, hızlı (ve kirli) bir yol, programın çalışmasına izin vermek, uzun süre uyumak ve bellek kullanımını kontrol etmektir (ör. : Mac'in etkinlik izleyicisi) bu belirli python işlemiyle. Bu, bir python işleminde tek bir büyük nesnenin boyutunu bulmaya çalıştığınızda etkili olacaktır. Örneğin, son zamanlarda yeni bir veri yapısının bellek kullanımını kontrol etmek ve Python'un set veri yapısıyla karşılaştırmak istedim. Önce öğeleri (büyük bir kamu malı kitaptan kelimeler) bir sete yazdım, sonra sürecin boyutunu kontrol ettim ve sonra aynı şeyi diğer veri yapısıyla yaptım. Bir set ile Python sürecinin yeni veri yapısının iki katı kadar bellek aldığını öğrendim. Yine, yapmazdın İşlem tarafından kullanılan belleğin nesnenin boyutuna tam olarak eşit olduğunu söyleyebilmeli. Nesnenin boyutu büyüdükçe, işlemin geri kalanı tarafından tüketilen bellek izlemeye çalıştığınız nesnenin boyutuna kıyasla önemsiz hale geldikçe bu da yakınlaşır.


1
Soru bunu nasıl sorar python sadece bellek kullanımını bulma, bir piton nesneleri ve programlı piton kullanmayan bir Mac aktivite monitör veya diğer benzer yazılım kullanarak. Bununla birlikte, python süreçlerinin bellek kullanımını bu şekilde kontrol etmek, genellikle hiçbir şeyin yanlış gitmediğinden emin olmak için iyi bir yoldur ...
Tom Wyllie

@TomWyllie, Teşekkürler, ancak bu cevabı aşağıya indirmek, cevabın kendisinin yanlış olduğu ve hiçbir şey başaramadığı olumsuz çağrışımı taşır. Bahsettiğim yöntem Python'da uygulanmayabilir, ancak bir Python nesnesinin boyutunun kaba bir tahminini almanın kullanışlı bir yoludur. Soruyu tam olarak yanıtlamadığımı biliyordum, ancak yöntem başka birinin benzer bir sonuç alması için yararlı olabilir.
picmate 涅

1

Bir nesnenin boyutunu belirlemek için aşağıda belirtildiği gibi getSizeof () yöntemini kullanabilirsiniz

import sys
str1 = "one"
int_element=5
print("Memory size of '"+str1+"' = "+str(sys.getsizeof(str1))+ " bytes")
print("Memory size of '"+ str(int_element)+"' = "+str(sys.getsizeof(int_element))+ " bytes")

0

Bu hileyi kullanıyorum ... Küçük nesnelerde doğru olmayabilir, ancak sys.getsizeof () yerine karmaşık bir nesne (pygame yüzeyi gibi) için çok daha doğru olduğunu düşünüyorum.

import pygame as pg
import os
import psutil
import time


process = psutil.Process(os.getpid())
pg.init()    
vocab = ['hello', 'me', 'you', 'she', 'he', 'they', 'we',
         'should', 'why?', 'necessarily', 'do', 'that']

font = pg.font.SysFont("monospace", 100, True)

dct = {}

newMem = process.memory_info().rss  # don't mind this line
Str = f'store ' + f'Nothing \tsurface use about '.expandtabs(15) + \
      f'0\t bytes'.expandtabs(9)  # don't mind this assignment too

usedMem = process.memory_info().rss

for word in vocab:
    dct[word] = font.render(word, True, pg.Color("#000000"))

    time.sleep(0.1)  # wait a moment

    # get total used memory of this script:
    newMem = process.memory_info().rss
    Str = f'store ' + f'{word}\tsurface use about '.expandtabs(15) + \
          f'{newMem - usedMem}\t bytes'.expandtabs(9)

    print(Str)
    usedMem = newMem

Windows 10, python 3.7.3'te çıktı:

store hello          surface use about 225280    bytes
store me             surface use about 61440     bytes
store you            surface use about 94208     bytes
store she            surface use about 81920     bytes
store he             surface use about 53248     bytes
store they           surface use about 114688    bytes
store we             surface use about 57344     bytes
store should         surface use about 172032    bytes
store why?           surface use about 110592    bytes
store necessarily    surface use about 311296    bytes
store do             surface use about 57344     bytes
store that           surface use about 110592    bytes
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.