-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
gh-126703: add freelist for ints with small number of digits #129638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 4 commits
3ccb908
b27a21e
a7cb1b3
f26f94a
312f3a0
e21b7c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Increase usage of freelist for :class:`int` allocation. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -153,6 +153,21 @@ long_normalize(PyLongObject *v) | |
| # define MAX_LONG_DIGITS ((INT64_MAX-1) / PyLong_SHIFT) | ||
| #endif | ||
|
|
||
| static inline int | ||
| maybe_freelist_push(PyObject *self) | ||
| { | ||
| assert(PyLong_CheckExact(self)); | ||
|
|
||
| PyLongObject *op = (PyLongObject *)self; | ||
| Py_ssize_t ndigits = _PyLong_DigitCount(op); | ||
|
|
||
| if (ndigits < PyLong_MAXSAVESIZE) { | ||
| return _Py_FREELIST_PUSH(ints[ndigits], self, Py_ints_MAXFREELIST); | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
|
|
||
| static PyLongObject * | ||
| long_alloc(Py_ssize_t size) | ||
| { | ||
|
|
@@ -167,8 +182,8 @@ long_alloc(Py_ssize_t size) | |
| * assume that there is always at least one digit present. */ | ||
| Py_ssize_t ndigits = size ? size : 1; | ||
|
|
||
| if (ndigits == 1) { | ||
| result = (PyLongObject *)_Py_FREELIST_POP(PyLongObject, ints); | ||
| if (ndigits < PyLong_MAXSAVESIZE ) { | ||
| result = (PyLongObject *)_Py_FREELIST_POP(PyLongObject, ints[ndigits]); | ||
| } | ||
| if (result == NULL) { | ||
| /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) + | ||
|
|
@@ -248,7 +263,7 @@ _PyLong_FromMedium(sdigit x) | |
| assert(!IS_SMALL_INT(x)); | ||
| assert(is_medium_int(x)); | ||
|
|
||
| PyLongObject *v = (PyLongObject *)_Py_FREELIST_POP(PyLongObject, ints); | ||
| PyLongObject *v = (PyLongObject *)_Py_FREELIST_POP(PyLongObject, ints[1]); | ||
| if (v == NULL) { | ||
| v = PyObject_Malloc(sizeof(PyLongObject)); | ||
| if (v == NULL) { | ||
|
|
@@ -3636,11 +3651,10 @@ _PyLong_ExactDealloc(PyObject *self) | |
| _Py_SetImmortal(self); | ||
| return; | ||
| } | ||
| if (_PyLong_IsCompact((PyLongObject *)self)) { | ||
| _Py_FREELIST_FREE(ints, self, PyObject_Free); | ||
| return; | ||
|
|
||
| if (!maybe_freelist_push(self)) { | ||
| PyObject_Free(self); | ||
| } | ||
| PyObject_Free(self); | ||
| } | ||
|
|
||
| static void | ||
|
|
@@ -3656,10 +3670,13 @@ long_dealloc(PyObject *self) | |
| _Py_SetImmortal(self); | ||
| return; | ||
| } | ||
| if (PyLong_CheckExact(self) && _PyLong_IsCompact((PyLongObject *)self)) { | ||
| _Py_FREELIST_FREE(ints, self, PyObject_Free); | ||
| if (PyLong_CheckExact(self)) { | ||
| if (!maybe_freelist_push(self)) { | ||
| PyObject_Free(self); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it equivalent to run There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is for exact ints (but might not be for subclasses). |
||
| } | ||
| return; | ||
| } | ||
|
|
||
| Py_TYPE(self)->tp_free(self); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why
ints[1]is used here?Maybe some comment on it will be useful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we need only ndigits==1 integers.
New implementation uses several free lists (though,
ints[0]isn't used).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ints[0]is indeed not used. It takes a tiny bit of extra memory, but makes the code cleaner.