Chiều dài đối tượng python

You can not get collect sub array count when use the key on only one sub array in an array:

$a = array["a"=>"appple", b"=>array['a'=>array[1,2,3],'b'=>array[1,2,3]]];
$b = array["a"=>"appple", "b"=>array[array['a'=>array[1,2,3],'b'=>array[1,2,3]], array[1,2,3],'b'=>array[1,2,3]], array['a'=>array[1,2,3],'b'=>array[1,2,3]]]];

echo count[$a['b']];  // 2 NOT 1, expect 1
echo count[$b['b']];  // 3,   expected

Câu trả lời đó thực sự hoạt động trực tiếp đối với các đối tượng dựng sẵn, nhưng nó không tính đến những đối tượng đó có thể chứa gì, cụ thể là loại nào, chẳng hạn như đối tượng tùy chỉnh, bộ dữ liệu, danh sách, ký tự và bộ chứa. Chúng có thể chứa các thể hiện của nhau, cũng như các số, chuỗi và các đối tượng khác

Một câu trả lời đầy đủ hơn

Sử dụng Python 64-bit 3. 6 từ bản phân phối Anaconda, với sys.getsizeof, tôi đã xác định kích thước tối thiểu của các đối tượng sau, đồng thời lưu ý rằng thiết lập và chỉ định không gian phân bổ trước để các đối tượng trống không tăng trở lại cho đến sau một số lượng đã đặt [có thể thay đổi tùy theo cách triển khai ngôn ngữ

Trăn 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.

Làm thế nào để bạn giải thích điều này? . Nếu mỗi mục là 100 byte, thì toàn bộ cấu trúc dữ liệu lớn đến mức nào? . Sau đó, bạn thêm kích thước của các mục, do đó tổng cộng là 1736 byte

Một số lưu ý đối với định nghĩa hàm và lớp

Lưu ý mỗi định nghĩa lớp có cấu trúc proxy __dict__ [48 byte] cho lớp attrs. Mỗi vị trí có một bộ mô tả [chẳng hạn như property] trong định nghĩa lớp

Các phiên bản có rãnh bắt đầu với 48 byte trên phần tử đầu tiên của chúng và tăng thêm 8 byte cho mỗi phần tử bổ sung. Chỉ các đối tượng có rãnh trống mới có 16 byte và một phiên bản không có dữ liệu có rất ít ý nghĩa

Ngoài ra, mỗi định nghĩa hàm có các đối tượng mã, có thể là chuỗi tài liệu và các thuộc tính có thể khác, thậm chí là một __dict__

Cũng lưu ý rằng chúng tôi sử dụng

    /* 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];
1 vì chúng tôi quan tâm đến việc sử dụng không gian biên, bao gồm chi phí thu gom rác cho đối tượng,

    /* 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];
2 gọi phương thứ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];
3 của đối tượng và thêm một bộ thu gom rác bổ sung nếu đối tượng được quản lý bởi bộ thu gom rác

Cũng lưu ý rằng thay đổi kích thước danh sách [e. g. lặp đi lặp lại nối thêm vào chúng] khiến chúng phân bổ trước không gian, tương tự như bộ và ký tự. Từ danh sáchobj. mã nguồn 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];

Dữ liệu lịch sử

Trăn 2. 7 phân tích, xác nhận với

    /* 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];
4 và 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.

Lưu ý rằng từ điển [nhưng không phải bộ] có trong Python 3. 6

Tôi nghĩ rằng 8 byte cho mỗi mục bổ sung để tham khảo rất có ý nghĩa trên máy 64 bit. 8 byte đó trỏ đến vị trí trong bộ nhớ mà mục được chứa tại. 4 byte có chiều rộng cố định cho unicode trong Python 2, nếu tôi nhớ chính xác, nhưng trong Python 3, str trở thành một unicode có chiều rộng bằng chiều rộng tối đa của các ký tự

Và để biết thêm về các vị trí, hãy xem câu trả lời này

Một chức năng hoàn chỉnh hơn

Chúng tôi muốn một chức năng tìm kiếm các phần tử trong danh sách, bộ dữ liệu, bộ, ký tự,

    /* 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];
6 và
    /* 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];
7, cũng như những thứ khác mà chúng tôi có thể chưa nghĩ đến

Chúng tôi muốn dựa vào

    /* 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];
8 để thực hiện tìm kiếm này vì nó hoạt động ở cấp độ C [làm cho nó rất nhanh]. Nhược điểm là get_referents có thể trả lại các thành viên dư thừa, vì vậy chúng tôi cần đảm bảo rằng chúng tôi không tính gấp đôi

Các lớp, mô-đun và chức năng là các đơn vị - chúng tồn tại một lần trong bộ nhớ. Chúng tôi không quá quan tâm đến kích thước của chúng, vì chúng tôi không thể làm gì nhiều với chúng - chúng là một phần của chương trình. Vì vậy, chúng tôi sẽ tránh đếm chúng nếu chúng được tham chiếu

Chúng tôi sẽ sử dụng danh sách đen các loại để chúng tôi không bao gồm toàn bộ chương trình trong số lượng kích thước của chúng tôi

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

Để đối chiếu điều này với chức năng được liệt kê trong danh sách trắng sau đây, hầu hết các đối tượng đều biết cách tự di chuyển để phục vụ mục đích thu gom rác [gần đúng với những gì chúng ta đang tìm kiếm khi muốn biết một số đối tượng nhất định đắt như thế nào trong bộ nhớ. Chức năng này được sử dụng bởi

    /* 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];
8. ] Tuy nhiên, biện pháp này sẽ có phạm vi mở rộng hơn nhiều so với dự định của chúng tôi nếu chúng tôi không cẩn thận

Ví dụ, các hàm biết khá nhiều về các mô-đun mà chúng được tạo trong

Một điểm tương phản khác là các chuỗi là khóa trong từ điển thường được thực hiện để chúng không bị trùng lặp. Việc kiểm tra

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.
0 cũng sẽ cho phép chúng tôi tránh đếm trùng lặp, điều mà chúng tôi sẽ thực hiện trong phần tiếp theo. Giải pháp danh sách đen bỏ qua việc đếm các khóa là chuỗi hoàn toàn

Loại danh sách trắng, khách truy cập đệ quy

Để tự mình giải quyết hầu hết các loại này, thay vì dựa vào mô-đun

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.
1, tôi đã viết hàm đệ quy này để thử ước tính kích thước của hầu hết các đối tượng Python, bao gồm hầu hết các nội trang, các loại trong mô-đun bộ sưu tập và các loại tùy chỉnh [có rãnh và các loại khác]

Loại chức năng này cho phép kiểm soát chi tiết hơn nhiều đối với các loại mà chúng tôi sẽ tính cho việc sử dụng bộ nhớ, nhưng có nguy cơ loại bỏ các loại quan trọng

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


ZERO_DEPTH_BASES = [str, bytes, Number, range, bytearray]


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, 'items']:
            size += sum[inner[k] + inner[v] for k, v in getattr[obj, 'items'][]]
        # 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]

Và tôi đã thử nghiệm nó khá tình cờ [tôi nên thử nghiệm nó]

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

Việc triển khai này phá vỡ các định nghĩa lớp và định nghĩa hàm vì chúng ta không theo dõi tất cả các thuộc tính của chúng, nhưng vì chúng chỉ tồn tại một lần trong bộ nhớ cho quy trình, nên kích thước của chúng thực sự không quá quan trọng

Chủ Đề