Bagaimana cara menentukan ukuran suatu objek dengan Python?

685

Saya ingin tahu cara mendapatkan ukuran objek seperti string, integer, dll dengan Python.

Pertanyaan terkait: Berapa banyak byte per elemen yang ada dalam daftar Python (tuple)?

Saya menggunakan file XML yang berisi bidang ukuran yang menentukan ukuran nilai. Saya harus menguraikan XML ini dan melakukan pengkodean. Ketika saya ingin mengubah nilai bidang tertentu, saya akan memeriksa bidang ukuran nilai itu. Di sini saya ingin membandingkan apakah nilai baru yang saya masukkan adalah dengan ukuran yang sama seperti dalam XML. Saya perlu memeriksa ukuran nilai baru. Dalam hal string saya bisa mengatakan panjangnya. Tetapi dalam hal int, float, dll. Saya bingung.

pengguna46646
sumber

Jawaban:

665

Cukup gunakan fungsi sys.getsizeof yang didefinisikan dalam sysmodul.

sys.getsizeof(object[, default]):

Kembalikan ukuran objek dalam byte. Objek dapat berupa semua jenis objek. Semua objek bawaan akan mengembalikan hasil yang benar, tetapi ini tidak harus berlaku untuk ekstensi pihak ketiga karena khusus implementasi.

The defaultargumen memungkinkan untuk mendefinisikan nilai yang akan dikembalikan jika jenis objek tidak menyediakan sarana untuk mengambil ukuran dan akan menyebabkan TypeError.

getsizeofmemanggil __sizeof__metode objek dan menambahkan overhead pengumpul sampah jika objek dikelola oleh pengumpul sampah.

Contoh penggunaan, dalam python 3.0:

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

Jika Anda menggunakan python <2.6 dan tidak memilikinya, sys.getsizeofAnda dapat menggunakan modul luas ini . Tapi tidak pernah menggunakannya.

nosklo
sumber
182
Silakan tambahkan ke penafian bahwa itu tidak akan berlaku untuk objek bersarang atau dicts bersarang atau dicts dalam daftar dll.
JohnnyM
8
@ ChaimG itu karena setiap objek hanya menggunakan 32 byte !! Sisanya adalah referensi ke objek lain. Jika Anda ingin menjelaskan objek yang direferensikan, Anda harus menentukan __sizeof__metode untuk kelas Anda. Built-in dictkelas python tidak mendefinisikannya, itu sebabnya Anda mendapatkan hasil yang benar saat menggunakan objek tipe dict.
nosklo
19
Penafian dan pengecualian untuk tutupan kerja ini hampir semua kasus penggunaan membuat getsizeoffungsi bernilai kecil di luar kotak.
Robino
7
mengapa integer 2 disimpan dalam 24 byte?
Saher Ahwal
4
@ SaherAhwal bukan hanya bilangan bulat, tetapi objek penuh dengan metode, atribut, alamat ...
nosklo
372

Bagaimana cara menentukan ukuran suatu objek dengan Python?

Jawabannya, "Cukup gunakan sys.getsizeof" bukan jawaban yang lengkap.

Jawaban itu memang berfungsi untuk objek builtin secara langsung, tetapi tidak menjelaskan apa yang mungkin berisi objek-objek itu, khususnya, jenis apa, seperti objek kustom, tupel, daftar, dikt, dan set berisi. Mereka dapat berisi instance satu sama lain, serta angka, string dan objek lainnya.

Jawaban yang Lebih Lengkap

Menggunakan 64 bit Python 3.6 dari distribusi Anaconda, dengan sys.getsizeof, saya telah menentukan ukuran minimum dari objek berikut, dan perhatikan bahwa set dan dicts mengalokasikan ruang sehingga yang kosong tidak tumbuh lagi sampai setelah jumlah yang ditentukan (yang mungkin bervariasi berdasarkan implementasi bahasa):

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.

Bagaimana Anda menafsirkan ini? Nah katakanlah Anda memiliki satu set dengan 10 item di dalamnya. Jika setiap item masing-masing 100 byte, seberapa besar seluruh struktur data? Set adalah 736 itu sendiri karena memiliki ukuran satu kali hingga 736 byte. Kemudian Anda menambahkan ukuran item, sehingga totalnya adalah 1736 byte

Beberapa peringatan untuk definisi fungsi dan kelas:

Perhatikan bahwa setiap definisi kelas memiliki struktur proxy __dict__(48 byte) untuk attr kelas. Setiap slot memiliki deskriptor (seperti a property) dalam definisi kelas.

Mesin Virtual Slotted memulai dengan 48 byte pada elemen pertama mereka, dan meningkat 8 masing-masing tambahan. Hanya objek slotted kosong yang memiliki 16 byte, dan sebuah instance tanpa data masuk akal sangat sedikit.

Juga, setiap definisi fungsi memiliki objek kode, mungkin dokumen, dan atribut lainnya yang mungkin, bahkan a __dict__.

Perhatikan juga bahwa kami menggunakan sys.getsizeof()karena kami peduli tentang penggunaan ruang marginal, yang mencakup pengumpulan sampah di atas objek, dari dokumen :

getsizeof () memanggil __sizeof__metode objek dan menambahkan overhead pengumpul sampah tambahan jika objek dikelola oleh pengumpul sampah.

Perhatikan juga bahwa mengubah ukuran daftar (misalnya menambahkannya secara berulang) menyebabkan mereka untuk melakukan pra-alokasi ruang, mirip dengan set dan dikt. Dari kode sumber listobj.c :

    /* 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);

Data historis

Analisis Python 2.7, dikonfirmasi dengan guppy.hpydan 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.

Perhatikan bahwa kamus ( tetapi bukan set ) mendapat representasi yang lebih ringkas dalam Python 3.6

Saya pikir 8 byte per item tambahan untuk referensi masuk akal pada mesin 64 bit. 8 byte itu menunjuk ke tempat di memori item yang terkandung. 4 byte adalah lebar tetap untuk unicode di Python 2, jika saya ingat dengan benar, tetapi dalam Python 3, str menjadi unicode dengan lebar sama dengan lebar maks karakter.

(Dan untuk lebih lanjut tentang slot, lihat jawaban ini )

Fungsi Yang Lebih Lengkap

Kami ingin fungsi yang mencari elemen dalam daftar, tupel, set, dikte obj.__dict__, danobj.__slots__ , serta hal-hal lain yang mungkin belum terpikirkan.

Kami ingin mengandalkan gc.get_referentsuntuk melakukan pencarian ini karena berfungsi pada level C (membuatnya sangat cepat). Kelemahannya adalah get_referents dapat mengembalikan anggota yang berlebihan, jadi kami perlu memastikan bahwa kami tidak menggandakan jumlah.

Kelas, modul, dan fungsi adalah lajang - mereka ada satu kali dalam memori. Kami tidak begitu tertarik dengan ukurannya, karena tidak banyak yang dapat kami lakukan tentang mereka - mereka adalah bagian dari program ini. Jadi kami akan menghindari menghitungnya jika mereka dirujuk.

Kami akan menggunakan daftar jenis hitam sehingga kami tidak memasukkan seluruh program dalam jumlah ukuran kami.

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

Untuk mengontraskan ini dengan fungsi daftar putih berikut, sebagian besar objek tahu cara melintasi dirinya untuk tujuan pengumpulan sampah (yang kira-kira apa yang kita cari ketika kita ingin tahu seberapa mahal dalam memori objek tertentu. Fungsi ini digunakan oleh gc.get_referents .) Namun, ukuran ini akan jauh lebih luas dalam ruang lingkup daripada yang kita maksudkan jika kita tidak hati-hati.

Sebagai contoh, fungsi tahu banyak tentang modul yang mereka buat.

Poin kontras lainnya adalah string yang merupakan kunci dalam kamus biasanya diinternir sehingga tidak terduplikasi. Memeriksa id(key)juga akan memungkinkan kami untuk menghindari penghitungan duplikat, yang kami lakukan di bagian selanjutnya. Solusi daftar hitam melompati tombol penghitungan yang merupakan string sekaligus.

Jenis Daftar Putih, pengunjung Rekursif (implementasi lama)

Untuk menutupi sebagian besar dari tipe ini sendiri, daripada mengandalkan modul gc, saya menulis fungsi rekursif ini untuk mencoba memperkirakan ukuran sebagian besar objek Python, termasuk sebagian besar builtin, tipe dalam modul koleksi, dan tipe khusus (slotted dan lainnya) .

Fungsi semacam ini memberikan kontrol yang jauh lebih baik atas jenis yang akan kita hitung untuk penggunaan memori, tetapi memiliki risiko mengabaikan jenis:

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)

Dan saya mengujinya dengan santai (saya harus melepasnya):

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

Implementasi ini rusak pada definisi kelas dan definisi fungsi karena kita tidak mengejar semua atribut mereka, tetapi karena mereka seharusnya hanya ada satu kali dalam memori untuk proses, ukurannya benar-benar tidak terlalu penting.

Aaron Hall
sumber
5
Anda dapat menambahkan bahwa jawaban ini khusus untuk CPython (yang tersirat oleh Anda mendapatkan Python melalui Anaconda)
gerrit
1
CPython adalah implementasi referensi, dan saya baru saja meninjau dokumen online jython yang menyediakan API yang sama, jadi saya percaya ini akan bekerja pada implementasi lain, selama mereka mengimplementasikan API.
Aaron Hall
bagi saya tidak bekerja untuk array numpy bertopeng dan terbuka kedok stackoverflow.com/q/58675479/2132157
GM
96

The Pympler paket ini asizeofmodul bisa melakukan ini.

Gunakan sebagai berikut:

from pympler import asizeof
asizeof.asizeof(my_object)

Tidak seperti sys.getsizeofitu, ini berfungsi untuk objek yang Anda buat sendiri . Bahkan bekerja dengan numpy.

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

Seperti yang disebutkan ,

Ukuran kode (byte) objek seperti kelas, fungsi, metode, modul, dll. Dapat disertakan dengan opsi pengaturan code=True.

Dan jika Anda membutuhkan tampilan lain pada data langsung, Pympler

modul muppydigunakan untuk pemantauan on-line dari aplikasi Python dan modul Class Trackermenyediakan analisis off-line dari masa hidup objek Python yang dipilih.

serv-inc
sumber
fungsi ini cukup lambat untuk objek yang lebih besar. Apakah ada persamaan "cepat" yang berfungsi untuk objek yang dibuat sendiri?
Shuklaswag
Saya belum mengujinya, tetapi org.apache.spark.util.SizeEstimatormungkin relevan
Shuklaswag
1
@Shuklaswag: jika Anda menggunakan percikan, itu mungkin saja. Apakah menurut Anda konversi + perkiraan Java lebih cepat daripada metode bawaan python? Atau apakah saya salah paham?
serv-inc
3
Mungkin patut dicatat yang pymplermemiliki kemampuan untuk mengambil ukuran kode fungsi yang dapat dieksekusi dan callable lainnya dan objek kode ke akun.
mtraceur
Saya mendapatkan TypeErrorpengecualian: "objek 'NoneType' tidak bisa dipanggil" setiap kali objek kustom saya memiliki beberapa subobjek di "tree" -nya dengan nilai None. Apakah ada solusi cepat untuk ini?
James Hirschorn
81

Untuk array numpy, getsizeoftidak berfungsi - bagi saya itu selalu mengembalikan 40 karena beberapa alasan:

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

Lalu (dengan ipython):

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

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

Untungnya, meskipun:

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

In [67]: B.nbytes
Out[67]: 80000
Mike Dewar
sumber
29
> Semua objek bawaan akan mengembalikan hasil yang benar, tetapi ini tidak harus berlaku untuk ekstensi pihak ketiga karena khusus implementasi. docs.python.org/library/sys.html#sys.getsizeof
warvariuc
33
"Jika Anda menggunakan array numpy ( docs.scipy.org/doc/numpy/reference/arrays.ndarray.html ) maka Anda dapat menggunakan atribut 'ndarray.nbytes' untuk mengevaluasi ukurannya dalam memori." stackoverflow.com/a/15591157/556413
glarrain
17
Saya kira 40 byte sudah benar, namun getsizeof()hanya memberi Anda ukuran objek (header array), bukan data di dalamnya. Sama untuk wadah python di mana sys.getsizeof([1,2,4]) == sys.getsizeof([1,123**456,4]) == 48, sementarasys.getsizeof(123**456) = 436
yota
3
Tampaknya getsizeof()fungsi diubah di beberapa titik untuk mengembalikan nilai yang diharapkan.
dshin
16

Python 3.8 (Q1 2019) akan mengubah beberapa hasil sys.getsizeof, seperti yang diumumkan di sini oleh Raymond Hettinger:

Kontainer Python berukuran 8 byte lebih kecil pada build 64-bit.

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

Ini muncul setelah edisi 33597 dan karya Inada Naoki ( methane) seputar Compact PyGC_Head, dan PR 7043

Gagasan ini mengurangi ukuran PyGC_Head menjadi dua kata .

Saat ini, PyGC_Head membutuhkan tiga kata ; gc_prev,, gc_nextdan gc_refcnt.

  • gc_refcnt digunakan saat mengumpulkan, untuk penghapusan percobaan.
  • gc_prev digunakan untuk melacak dan tidak melacak.

Jadi, jika kita dapat menghindari pelacakan / pelacakan saat penghapusan percobaan, gc_prevdan gc_refcntdapat berbagi ruang memori yang sama.

Lihat komit d5c875b :

Menghapus satu Py_ssize_tanggota dari PyGC_Head.
Semua objek yang dilacak GC (misalnya tupel, daftar, dikt) ukuran dikurangi 4 atau 8 byte.

VONC
sumber
14

Ini bisa lebih rumit daripada yang terlihat tergantung pada bagaimana Anda ingin menghitung sesuatu. Misalnya, jika Anda memiliki daftar int, apakah Anda ingin ukuran daftar yang berisi referensi ke int? (mis. hanya daftar, bukan apa yang terkandung di dalamnya), atau apakah Anda ingin menyertakan data aktual yang ditunjukkan, dalam hal ini Anda harus berurusan dengan referensi rangkap, dan bagaimana mencegah penghitungan ganda ketika dua objek berisi referensi untuk objek yang sama.

Anda mungkin ingin melihat salah satu profiler memori python, seperti pysizer untuk melihat apakah mereka memenuhi kebutuhan Anda.

Brian
sumber
10

Setelah mengalami masalah ini berkali-kali sendiri, saya menulis fungsi kecil (terinspirasi oleh jawaban @ aaron-hall) & tes yang melakukan apa yang saya harapkan sys.getsizeof lakukan:

https://github.com/bosswissam/pysize

Jika Anda tertarik pada latar belakang, ini dia

EDIT: Melampirkan kode di bawah ini untuk referensi mudah. Untuk melihat kode terbaru, silakan periksa tautan github.

    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
wissam
sumber
7

Berikut ini adalah skrip cepat yang saya tulis berdasarkan jawaban sebelumnya untuk daftar ukuran semua variabel

for i in dir():
    print (i, sys.getsizeof(eval(i)) )
alexey
sumber
Itu tidak salah, itu ambigu. sys.getsizeof akan selalu mengembalikan nilai yang diperlukan, sehingga tidak perlu kehilangan kinerja dengan coba..kecuali.
der_fenix
oh, itu poin yang bagus dan saya tidak memikirkannya - kode dalam bentuknya sekarang hanya menunjukkan bagaimana itu ditulis secara kronologis - pertama saya tahu tentang numpy (maka nbytes), kemudian saya mencari solusi yang lebih umum . Terima kasih atas penjelasannya _ / \ _
alexey
7

Anda bisa membuat serial objek untuk mendapatkan ukuran yang terkait erat dengan ukuran objek:

import pickle

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

Jika Anda ingin mengukur objek yang tidak dapat diasamkan (misalnya karena ekspresi lambda) cloudpickle dapat menjadi solusi.

Some one
sumber
4

Gunakan sys.getsizeof () jika Anda TIDAK ingin menyertakan ukuran objek yang terhubung (bersarang).

Namun, jika Anda ingin menghitung sub-objek yang bersarang dalam daftar, dicts, set, tuple - dan biasanya INI yang Anda cari - gunakan fungsi deep sizeof () rekursif () seperti yang ditunjukkan di bawah ini:

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

Anda juga dapat menemukan fungsi ini di kotak peralatan bagus , bersama dengan banyak satu-liners berguna lainnya:

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

Marcin Wojnarski
sumber
3

Jika Anda tidak membutuhkan ukuran objek yang tepat tetapi secara kasar mengetahui seberapa besar benda itu, satu cara cepat (dan kotor) adalah membiarkan program berjalan, tidur untuk waktu yang lama, dan memeriksa penggunaan memori (mis. : Monitor aktivitas Mac) dengan proses python khusus ini. Ini akan efektif ketika Anda mencoba menemukan ukuran satu objek besar tunggal dalam proses python. Sebagai contoh, saya baru-baru ini ingin memeriksa penggunaan memori dari struktur data baru dan membandingkannya dengan struktur data yang ditetapkan Python. Pertama saya menulis elemen (kata-kata dari buku domain publik besar) ke set, kemudian memeriksa ukuran proses, dan kemudian melakukan hal yang sama dengan struktur data lainnya. Saya menemukan proses Python dengan satu set mengambil dua kali lebih banyak memori daripada struktur data baru. Sekali lagi, kamu tidak akan t dapat dengan tepat mengatakan memori yang digunakan oleh proses sama dengan ukuran objek. Ketika ukuran objek semakin besar, ini menjadi dekat karena memori yang dikonsumsi oleh sisa proses menjadi diabaikan dibandingkan dengan ukuran objek yang Anda coba pantau.

teman satu 涅
sumber
1
Pertanyaannya bertanya bagaimana melakukannya di python , tidak hanya menemukan penggunaan memori dari objek python, dan menggunakan Mac aktivitas monitor atau perangkat lunak lainnya yang sejenis tidak pemrograman menggunakan python. Yang sedang berkata, memeriksa penggunaan memori proses python dengan cara ini umumnya adalah cara yang baik untuk memastikan tidak ada yang salah ...
Tom Wyllie
@ TomWyllie, Terima kasih, tetapi menolak jawaban ini membawa konotasi negatif bahwa jawaban itu sendiri salah dan tidak menghasilkan apa-apa. Metode yang saya sebutkan mungkin tidak diimplementasikan dalam Python, tetapi ini adalah cara praktis untuk mendapatkan perkiraan kasar ukuran objek Python. Saya tahu saya tidak menjawab pertanyaan yang tepat, namun metode ini dapat berguna bagi orang lain untuk mendapatkan hasil yang serupa.
picmate 涅
1

Anda dapat menggunakan getSizeof () seperti yang disebutkan di bawah ini untuk menentukan ukuran objek

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")
forkdbloke
sumber
0

Saya menggunakan trik ini ... Mungkin tidak akan akurat pada objek kecil, tapi saya pikir itu jauh lebih akurat untuk objek yang kompleks (seperti permukaan pygame) daripada sys.getsizeof ()

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

Di windows 10 saya, python 3.7.3, hasilnya adalah:

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
Hzzkygcs
sumber