mirror of
https://github.com/python/cpython.git
synced 2025-12-05 00:52:25 +00:00
Issue #28731: Optimize _PyDict_NewPresized() to create correct size dict
Improve speed of dict literal with constant keys up to 30%.
This commit is contained in:
parent
c0be040b48
commit
92c50eee52
2 changed files with 22 additions and 5 deletions
|
|
@ -10,6 +10,9 @@ What's New in Python 3.7.0 alpha 1
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #28731: Optimize _PyDict_NewPresized() to create correct size dict.
|
||||||
|
Improve speed of dict literal with constant keys up to 30%.
|
||||||
|
|
||||||
- Issue #28532: Show sys.version when -V option is supplied twice.
|
- Issue #28532: Show sys.version when -V option is supplied twice.
|
||||||
|
|
||||||
- Issue #28746: Fix the set_inheritable() file descriptor method on platforms
|
- Issue #28746: Fix the set_inheritable() file descriptor method on platforms
|
||||||
|
|
|
||||||
|
|
@ -389,7 +389,7 @@ dk_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix)
|
||||||
* This can be used to reserve enough size to insert n entries without
|
* This can be used to reserve enough size to insert n entries without
|
||||||
* resizing.
|
* resizing.
|
||||||
*/
|
*/
|
||||||
#define ESTIMATE_SIZE(n) (((n)*3) >> 1)
|
#define ESTIMATE_SIZE(n) (((n)*3+1) >> 1)
|
||||||
|
|
||||||
/* Alternative fraction that is otherwise close enough to 2n/3 to make
|
/* Alternative fraction that is otherwise close enough to 2n/3 to make
|
||||||
* little difference. 8 * 2/3 == 8 * 5/8 == 5. 16 * 2/3 == 16 * 5/8 == 10.
|
* little difference. 8 * 2/3 == 8 * 5/8 == 5. 16 * 2/3 == 16 * 5/8 == 10.
|
||||||
|
|
@ -1361,12 +1361,26 @@ make_keys_shared(PyObject *op)
|
||||||
PyObject *
|
PyObject *
|
||||||
_PyDict_NewPresized(Py_ssize_t minused)
|
_PyDict_NewPresized(Py_ssize_t minused)
|
||||||
{
|
{
|
||||||
|
const Py_ssize_t max_presize = 128 * 1024;
|
||||||
Py_ssize_t newsize;
|
Py_ssize_t newsize;
|
||||||
PyDictKeysObject *new_keys;
|
PyDictKeysObject *new_keys;
|
||||||
for (newsize = PyDict_MINSIZE;
|
|
||||||
newsize <= minused && newsize > 0;
|
/* There are no strict guarantee that returned dict can contain minused
|
||||||
newsize <<= 1)
|
* items without resize. So we create medium size dict instead of very
|
||||||
;
|
* large dict or MemoryError.
|
||||||
|
*/
|
||||||
|
if (minused > USABLE_FRACTION(max_presize)) {
|
||||||
|
newsize = max_presize;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Py_ssize_t minsize = ESTIMATE_SIZE(minused);
|
||||||
|
newsize = PyDict_MINSIZE;
|
||||||
|
while (newsize < minsize) {
|
||||||
|
newsize <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(IS_POWER_OF_2(newsize));
|
||||||
|
|
||||||
new_keys = new_keys_object(newsize);
|
new_keys = new_keys_object(newsize);
|
||||||
if (new_keys == NULL)
|
if (new_keys == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue