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']] 3401 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']] 3401. 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']] 3403.
Đâ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']] 3404 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']] 3401:
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']] 3401 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']] 3401 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'}] 6280, 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'}] 6281. Có hai sự khác biệt chính giữa
>>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}] 6282 và
>>> objsize.get_deep_size[['hello', 'world'], dict[arg1='hello', arg2='world'], {'hello', 'world'}] 6283.
>>> 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ó.
>>> 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'}] 6282 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'}] 6282 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'}] 6282 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.10
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.11
Sau đó sử dụng nó như sau:
pip install objsize==0.6.12
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'}] 6282 để 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.13
Sau đó sử dụng những thứ này như sau:
pip install objsize==0.6.14
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] 7080.
pip install objsize==0.6.15
Để 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.16
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'}] 6282 để 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.18
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] 7080.
pip install objsize==0.6.19
Để 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']] 3400
pip install objsize==0.6.1
7
BSD-3