Hướng dẫn python size of object deep - trăn kích thước của vật thể sâu

Tôi muốn tính toán bộ nhớ được sử dụng bởi một đối tượng.

>>> import objsize
>>> objsize.get_deep_size[dict[arg1='hello', arg2='world']]
340
1 là tuyệt vời, nhưng là nông [ví dụ, được gọi trong danh sách, nó sẽ không bao gồm bộ nhớ được thực hiện bởi các yếu tố của danh sách].

Tôi muốn viết một phiên bản "Deep" chung chung của

>>> import objsize
>>> objsize.get_deep_size[dict[arg1='hello', arg2='world']]
340
1. Tôi hiểu có một số sự mơ hồ trong định nghĩa của "Deep"; Tôi hoàn toàn hài lòng với định nghĩa theo sau là
>>> import objsize
>>> objsize.get_deep_size[dict[arg1='hello', arg2='world']]
340
3.

Đây là nỗ lực đầu tiên của tôi:

def get_deep_sizeof[x, level=0, processed=None]:
    if processed is None:
        # we're here only if this function is called by client code, not recursively
        processed = set[]
    processed.add[id[x]]
    mem = sys.getsizeof[x]
    if isinstance[x, collections.Iterable] and not isinstance[x, str]:
        for xx in x:
            if id[xx] in processed:
                continue
            mem += get_deep_sizeof[xx, level+1, processed]
            if isinstance[x, dict]:
                mem += get_deep_sizeof[x[xx], level+1, processed]
    return mem

Nó bị hai vấn đề đã biết và một số vấn đề chưa biết chưa biết:

  • Tôi không biết làm thế nào để vượt qua một thùng chứa chung theo cách nắm bắt tất cả các đối tượng được liên kết. Do đó, tôi đã lặp lại bằng cách sử dụng
    >>> import objsize
    >>> objsize.get_deep_size[dict[arg1='hello', arg2='world']]
    340
    
    4 và cứng mã hóa trường hợp từ điển [để bao gồm các giá trị và không chỉ các khóa]. Rõ ràng, điều này sẽ không hoạt động cho các lớp khác như từ điển.
  • Tôi đã phải mã cứng loại trừ
    >>> import objsize
    >>> objsize.get_deep_size[dict[arg1='hello', arg2='world']]
    340
    
    5 [đó là một điều không thể điều chỉnh được và chưa có liên kết đến bất kỳ đối tượng nào khác]. Một lần nữa, điều này sẽ phá vỡ nếu có nhiều đối tượng như thế.

Tôi nghi ngờ rằng sử dụng

>>> import objsize
>>> objsize.get_deep_size[dict[arg1='hello', arg2='world']]
340
4 không phải là một ý tưởng tốt, nhưng tôi không chắc phải làm gì khác.

TL; DR: Sử dụng tập lệnh này để đo kích thước của các đối tượng trong Python. Điều này hoạt động cho các vòng lặp, các dicts và các lớp con của lớp đối tượng tích hợp Python.: Use this script to measure sizes of objects in Python. This works for iterables, dicts and subclasses of Python’s built-in Object class.

Chỉnh sửa: Cảm ơn những người đã đóng góp 🙂 Xin vui lòng gửi yêu cầu kéo cho bất kỳ trường hợp cạnh nào bạn gặp. & NBSP;

Một vài tháng trước, tôi nghi ngờ một biến toàn cầu là nguyên nhân gốc rễ của rò rỉ bộ nhớ. Tôi đã có đủ bằng chứng thực nghiệm để loại bỏ nó khỏi các hệ thống sản xuất của chúng tôi, tuy nhiên không đủ để thỏa mãn mọt sách bên trong của tôi.

Để làm điều đó, tôi đã phải đo kích thước đối tượng trong bộ nhớ, điều đáng ngạc nhiên là không phải là một điều đơn giản để làm trong Python. Nhìn vào các câu trả lời hàng đầu của StackOverflow để đo kích thước đối tượng Python, đã được thỏa mãn vì chúng chỉ chỉ vào các đoạn mã lớn mà tôi phải sử dụng để sử dụng mã của tôi và chúng bị quá mức.

Điều làm cho điều này tồi tệ hơn là các tài liệu Python khó hiểu về

>>> import objsize
>>> objsize.get_deep_size[dict[arg1='hello', arg2='world']]
340
1:

Trả về kích thước của một đối tượng trong byte. Đối tượng có thể là bất kỳ loại đối tượng. Tất cả các đối tượng tích hợp sẽ trả về kết quả chính xác, nhưng điều này không phải đúng với các tiện ích mở rộng của bên thứ ba vì nó là triển khai cụ thể.

Trả về kích thước của một đối tượng trong byte. Đối tượng có thể là bất kỳ loại đối tượng. Tất cả các đối tượng tích hợp sẽ trả về kết quả chính xác, nhưng điều này không phải đúng với các tiện ích mở rộng của bên thứ ba vì nó là triển khai cụ thể.

Từ quan điểm OOP, điều này không đúng. Khi bạn đo kích thước của một đối tượng, bạn thực sự muốn kích thước của tất cả các thuộc tính và các thuộc tính của chúng, v.v.

>>> import objsize
>>> objsize.get_deep_size[dict[arg1='hello', arg2='world']]
340
1 chỉ cung cấp cho bạn kích thước của đối tượng và các thuộc tính của chúng, tuy nhiên nó không thêm kích thước của phụ- thuộc tính.

Vì vậy, tôi quyết định điền vào khoảng trống. Tôi đã viết người trợ giúp dưới đây để đo lường kích thước của một đối tượng Python [hoặc dict, tuple, danh sách, v.v.]. Nó sử dụng

>>> import objsize
>>> objsize.get_deep_size[dict[arg1='hello', arg2='world']]
340
1 trong nội bộ và hóa ra là khá dễ dàng để viết một khi tôi đã tìm ra đủ các trường hợp cạnh.

Tôi hy vọng nó sẽ giúp lần tới khi bạn cần đo chính xác kích thước của một đối tượng!

Nhân tiện, chúng tôi tuyển dụng tại Shippo! Chúng tôi làm việc & nbsp; với & nbsp; Python, & nbsp; Emberjs và PostgreSql. & Nbsp; tàu API của chúng tôi & nbsp; hàng triệu gói trên khắp thế giới.

Shippo là một API và ứng dụng Web đa mang theo giúp các nhà bán lẻ, thị trường và nền tảng kết nối với một mạng lưới các nhà mạng toàn cầu. Các doanh nghiệp sử dụng Shippo để có được mức giá thời gian thực, in nhãn, tự động hóa giấy tờ quốc tế, theo dõi các gói và tạo điều kiện trả lại. Shippo cung cấp các công cụ để giúp các doanh nghiệp thành công thông qua vận chuyển.

@Chaimg đó là bởi vì mọi đối tượng chỉ sử dụng 32 byte !! Phần còn lại là các tham chiếu đến các đối tượng khác. Nếu bạn muốn tính đến các đối tượng được tham chiếu, bạn phải xác định phương thức __sizeOf__ cho lớp của bạn. Lớp Python Dict-in tích hợp không xác định nó, đó là lý do tại sao bạn nhận được kết quả chính xác khi sử dụng đối tượng của Dict Dict.

Loading...

Traversal trên các đối tượng của Python Subtree và tính toán tổng kích thước của cây con trong byte [kích thước sâu].

Mô -đun này đi qua tất cả các đối tượng con bằng cách sử dụng triển khai GC nội bộ của Python. Nó cố gắng bỏ qua các đối tượng được chia sẻ [nghĩa là,

>>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}]
628
0, các loại, mô -đun, lớp, chức năng, lambdas], vì chúng là phổ biến trong tất cả các đối tượng. Nó được thực hiện mà không cần các cuộc gọi đệ quy cho hiệu suất cao.

Đặc trưng

  • Subtree của Traverse Objects
  • Tính toán kích thước [sâu] đối tượng trong byte
  • Loại trừ các đối tượng không độc quyền
  • Loại trừ các đối tượng được chỉ định Subtree
  • Cho phép người dùng chỉ định trình xử lý duy nhất cho:
    • Tính toán kích thước của đối tượng
    • Giới thiệu của đối tượng [tức là, con cái của nó]
    • Bộ lọc đối tượng [Bỏ qua các đối tượng cụ thể]

Pympler cũng hỗ trợ xác định kích thước sâu đối tượng thông qua

>>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}]
628
1. Có hai sự khác biệt chính giữa
>>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}]
628
2 và
>>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}]
628
3.

  1. >>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}]
    628
    
    2 có các tính năng bổ sung:
    • Đi qua đối tượng Subtree: Lặp lại tất cả các hậu duệ của đối tượng từng cái một.
    • Không bao gồm các đối tượng không độc quyền. Đó là, các đối tượng cũng được tham chiếu từ một nơi khác trong chương trình. Điều này đúng để tính toán kích thước sâu của đối tượng và đi qua con cháu của nó.
  2. >>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}]
    628
    
    2 có một triển khai đơn giản và mạnh mẽ với các dòng mã ít hơn đáng kể, so với
    >>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}]
    628
    
    3. Việc triển khai pympler sử dụng đệ quy và do đó phải sử dụng một đối số độ sâu tối đa để tránh đạt được độ sâu tối đa của Python.
    >>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}]
    628
    
    2, tuy nhiên, sử dụng BFS hiệu quả hơn và đơn giản hơn để theo dõi. Hơn nữa, việc triển khai Pympler cẩn thận chăm sóc bất kỳ loại đối tượng nào.
    >>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}]
    628
    
    2 Lưu trữ cùng một mục tiêu với một triển khai đơn giản và chung chung, có ít dòng mã hơn.

Cài đặt

pip install objsize==0.6.1

Cách sử dụng cơ bản

Tính kích thước của đối tượng bao gồm tất cả các thành viên của nó trong byte.

>>> import objsize
>>> objsize.get_deep_size[dict[arg1='hello', arg2='world']]
340

Có thể tính toán kích thước sâu của nhiều đối tượng bằng cách truyền nhiều đối số:

>>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}]
628

Dữ liệu phức tạp

>>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}]
628
2 có thể tính toán kích thước của toàn bộ cây con của một đối tượng trong byte bất kể loại đối tượng trong đó và độ sâu của nó.

Dưới đây là một cấu trúc dữ liệu phức tạp, ví dụ, bao gồm một tài liệu tham khảo tự:

my_data = [list[range[3]], list[range[3, 6]]]


class MyClass:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
        self.d = {'x': x, 'y': y, 'self': self}

    def __repr__[self]:
        return "MyClass"


my_obj = MyClass[*my_data]

Chúng ta có thể tính toán kích thước sâu

my_data = [list[range[3]], list[range[3, 6]]]


class MyClass:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
        self.d = {'x': x, 'y': y, 'self': self}

    def __repr__[self]:
        return "MyClass"


my_obj = MyClass[*my_data]
0, bao gồm cả dữ liệu được lưu trữ của nó.

>>> objsize.get_deep_size[my_obj]
708

Chúng ta có thể muốn bỏ qua các đối tượng không độc quyền như các đối tượng được lưu trữ trong

my_data = [list[range[3]], list[range[3, 6]]]


class MyClass:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
        self.d = {'x': x, 'y': y, 'self': self}

    def __repr__[self]:
        return "MyClass"


my_obj = MyClass[*my_data]
1.

>>> objsize.get_deep_size[my_obj, exclude=[my_data]]
384

Hoặc đơn giản là để

>>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}]
628
2 phát hiện tự động đó:

>>> objsize.get_exclusive_deep_size[my_obj]
384

Các chức năng hoặc lớp không được chia sẻ

>>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}]
628
2 Bộ lọc chức năng, lambdas và các lớp theo mặc định vì chúng thường được chia sẻ giữa nhiều đối tượng. Ví dụ:

>>> method_dict = {"identity": lambda x: x, "double": lambda x: x*2}
>>> objsize.get_deep_size[method_dict]
232

Tuy nhiên, một số đối tượng như được minh họa trong ví dụ trên, có các chức năng duy nhất không được chia sẻ bởi các đối tượng khác. Do đó, nó có thể hữu ích để đếm kích thước của chúng. Bạn có thể đạt được điều này bằng cách cung cấp một chức năng bộ lọc thay thế.

>>> objsize.get_deep_size[method_dict, filter_func=objsize.shared_object_filter]
986

Notes:

  • Hàm bộ lọc mặc định là
    my_data = [list[range[3]], list[range[3, 6]]]
    
    
    class MyClass:
        def __init__[self, x, y]:
            self.x = x
            self.y = y
            self.d = {'x': x, 'y': y, 'self': self}
    
        def __repr__[self]:
            return "MyClass"
    
    
    my_obj = MyClass[*my_data]
    
    4.
  • Khi sử dụng
    my_data = [list[range[3]], list[range[3, 6]]]
    
    
    class MyClass:
        def __init__[self, x, y]:
            self.x = x
            self.y = y
            self.d = {'x': x, 'y': y, 'self': self}
    
        def __repr__[self]:
            return "MyClass"
    
    
    my_obj = MyClass[*my_data]
    
    5, các chức năng được chia sẻ và lambdas cũng được tính, nhưng các hàm tích hợp vẫn bị loại trừ.

Trường hợp đặc biệt

Một số đối tượng xử lý dữ liệu của họ theo cách ngăn GC của Python phát hiện nó. Người dùng có thể cung cấp một cách đặc biệt để tính toán kích thước thực tế của các đối tượng này.

Trường hợp 1:
my_data = [list[range[3]], list[range[3, 6]]]


class MyClass:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
        self.d = {'x': x, 'y': y, 'self': self}

    def __repr__[self]:
        return "MyClass"


my_obj = MyClass[*my_data]
6

Sử dụng tính toán đơn giản về kích thước đối tượng sẽ không hoạt động cho

my_data = [list[range[3]], list[range[3, 6]]]


class MyClass:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
        self.d = {'x': x, 'y': y, 'self': self}

    def __repr__[self]:
        return "MyClass"


my_obj = MyClass[*my_data]
7.

pip install objsize==0.6.1
0

Vì vậy, người dùng có thể xác định trình xử lý tính toán kích thước của riêng mình cho các trường hợp như vậy:

pip install objsize==0.6.1
1

Sau đó sử dụng nó như sau:

pip install objsize==0.6.1
2

Tuy nhiên, điều này bỏ qua cấu trúc bên trong của đối tượng. Người dùng có thể giúp

>>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}]
628
2 để tìm lưu trữ ẩn của đối tượng bằng cách cung cấp cho nó các chức năng giới thiệu và bộ lọc của riêng mình:

pip install objsize==0.6.1
3

Sau đó sử dụng những thứ này như sau:

pip install objsize==0.6.1
4

Trường hợp 2:
my_data = [list[range[3]], list[range[3, 6]]]


class MyClass:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
        self.d = {'x': x, 'y': y, 'self': self}

    def __repr__[self]:
        return "MyClass"


my_obj = MyClass[*my_data]
9

Sử dụng tính toán đơn giản về kích thước đối tượng sẽ không hoạt động cho

>>> objsize.get_deep_size[my_obj]
708
0.

pip install objsize==0.6.1
5

Để giảm thiểu điều này, bạn có thể cung cấp một phương thức cố gắng tìm nạp các giới thiệu của proxy:

pip install objsize==0.6.1
6

Sau đó sử dụng nó như sau:

Tuy nhiên, điều này bỏ qua cấu trúc bên trong của đối tượng. Người dùng có thể giúp
>>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}]
628
2 để tìm lưu trữ ẩn của đối tượng bằng cách cung cấp cho nó các chức năng giới thiệu và bộ lọc của riêng mình:

Sau đó sử dụng những thứ này như sau:

pip install objsize==0.6.1
8

Trường hợp 2:
my_data = [list[range[3]], list[range[3, 6]]]


class MyClass:
    def __init__[self, x, y]:
        self.x = x
        self.y = y
        self.d = {'x': x, 'y': y, 'self': self}

    def __repr__[self]:
        return "MyClass"


my_obj = MyClass[*my_data]
9

Sử dụng tính toán đơn giản về kích thước đối tượng sẽ không hoạt động cho

>>> objsize.get_deep_size[my_obj]
708
0.

pip install objsize==0.6.1
9

Để giảm thiểu điều này, bạn có thể cung cấp một phương thức cố gắng tìm nạp các giới thiệu của proxy:

>>> import objsize
>>> objsize.get_deep_size[dict[arg1='hello', arg2='world']]
340
0

pip install objsize==0.6.1
7

BSD-3

Làm cách nào để xác định kích thước của một đối tượng trong Python?

Trong Python, việc sử dụng sys.getsizeOf [] có thể được thực hiện để tìm kích thước lưu trữ của một đối tượng cụ thể chiếm một số không gian trong bộ nhớ. Hàm này trả về kích thước của đối tượng trong byte.sys. getsizeof[] can be done to find the storage size of a particular object that occupies some space in the memory. This function returns the size of the object in bytes.

Có bao nhiêu byte là một đối tượng Python?

@Chaimg đó là bởi vì mọi đối tượng chỉ sử dụng 32 byte !!Phần còn lại là các tham chiếu đến các đối tượng khác.Nếu bạn muốn tính đến các đối tượng được tham chiếu, bạn phải xác định phương thức __sizeOf__ cho lớp của bạn.Lớp Python Dict-in tích hợp không xác định nó, đó là lý do tại sao bạn nhận được kết quả chính xác khi sử dụng đối tượng của Dict Dict.32 bytes!! The rest are references to other objects. If you want to account for the referenced objects you have to define __sizeof__ method for your class. The built-in dict python class does define it, that's why you get the correct result when using object of type dict .

__ sizeof __ trong Python là gì?

Hàm __sizeof __ [] trong Python không chính xác cho chúng ta biết kích thước của đối tượng.Nó không trả về kích thước của một đối tượng máy phát vì Python không thể cho chúng ta biết trước rằng kích thước của một máy phát là bao nhiêu.Tuy nhiên, trong thực tế, nó trả về kích thước bên trong cho một đối tượng cụ thể [tính bằng byte] chiếm bộ nhớ.it returns the internal size for a particular object [in bytes] occupying the memory.

Làm thế nào để bạn tìm thấy kích thước của một đối tượng?

Một cách để có được ước tính kích thước của một đối tượng trong Java là sử dụng phương thức GetObjectSize [Object] của giao diện thiết bị được giới thiệu trong Java 5. Như chúng ta có thể thấy trong tài liệu Javadoc, phương pháp cung cấp xấp xỉ cụ thể thực hiện trên mạng của đối tượng được chỉ định của đối tượng được chỉ địnhkích thước.use getObjectSize[Object] method of the Instrumentation interface introduced in Java 5. As we could see in Javadoc documentation, the method provides “implementation-specific approximation” of the specified object's size.

Bài Viết Liên Quan

Chủ Đề