The examples of "c extern" in the "Doc/includes/newtypes" directory of Python 3.11 and later versions need to be optimized, the memory structure of the `__dict__` in the C extern example under `Doc/includes/newtypes` is outdated.
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- Python
- Star
- 77.2k
- Fork
- 35.9k
- Chỉ số merge pull request
- Chỉ số pull request đang chờ
Mô tả
Documentation
For Python 3.11 and later, refer to:
https://github.com/faster-cpython/ideas/issues/80 (implementation details in CPython source: _PyObject_InitializeDict)
https://www.youtube.com/watch?v=xKk7IXm0XO0
The memory structure of the Python object dict pointer (dict ptr) is optimized:
However, in CPython directory Doc/includes/newtypes, the C extern example that involves adding a __dict__, such as:
from custom2 import Custom
class ItemData2(Custom): // c-extern dict-ptr is old-style memory structure
def __init__(self):
self.itemid = 0
self.item = 0
still uses the old dict ptr structure (prior to Python 3.10).
This involves two issues:
- The
dict ptrstructure uses the previous type (as stated above) - The
dict ptrmemory optimization in Python 3.11 and later does not work in the C extern example:
The memory optimization in _PyObject_InitializeDict->init_inline_values is not utilized:
static int
init_inline_values(PyObject *obj, PyTypeObject *tp)
{
assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE);
// assert(type->tp_dictoffset > 0); -- TODO: Update this assert.
assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT);
PyDictKeysObject *keys = CACHED_KEYS(tp);
assert(keys != NULL);
if (keys->dk_usable > 1) {
keys->dk_usable--; // Key optimization for memory when creating many objects with __dict__
}
}
When objects are created in large quantities, the memory per single object can differ by nearly 200 ~ 300bytes 。
detail
memory of ItemData2 = 392 bytes
typedef struct {
PyObject_HEAD
} CustomObject; # remove custom2.c CustomObject field: first, last, number
"The memory size allocated for new_values as PyDictValues is determined by arg size 。
arg size default value is 30(when the __dict__ contains fewer than 30 members):
When arg size is 30, the memory size of PyDictValues is 272 bytes:"
total size:
56(object ptr basic) + 64(dict ptr) + 0(cache key ptr, shared memory) + 272(values ptr) = 392 bytes
memory of ItemData = 104 bytes
when the __dict__ contains 2 memebers:
memory of values ptr = prefix_size + size * sizeof(PyObject*) = prefix_size + (dk_entries + dk_usable) * sizeof(PyObject*)
= 32 + (2 + 0) * 8 = 48 bytes
56(object basic memory) + 0(dict ptr) + 0(cache key, shared) + 48(value ptr)= 104 bytes
I try to fix it, like:
static PyObject *
Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
CustomObject *self;
// 直接调用object.tp_new, 注意不要把 args 直接传PyBaseObject_Type.tp_new,`__init__`带参数时会报错
static PyObject* intern_tuple0 = NULL;
if (intern_tuple0 == NULL)
intern_tuple0 = PyTuple_New(0);
self = PyBaseObject_Type.tp_new(type, intern_tuple0, NULL);
//self = (CustomObject *) type->tp_alloc(type, 0);
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu trong Doc/includes/newtypes và kiểm tra các ví dụ C extern thêm một dict, sau đó so sánh hành vi cấp phát của chúng với Python 3.11+ và _PyObject_InitializeDict. Sử dụng faster-cpython issue được tham chiếu và các chi tiết triển khai của CPython để xác định cấu trúc hiện tại; hoàn thành nghĩa là các ví dụ phản ánh layout được hỗ trợ và sử dụng tối ưu hóa bộ nhớ dự kiến.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- c, python
- Lĩnh vực
- documentation
- Loại issue
- Tài liệu
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 25/100