You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Improve list() pre-sizing for inputs with known lengths #77415
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2018-12-29.22:33:35.758>created_at=<Date2018-04-05.21:46:53.136>labels= ['interpreter-core', '3.8', 'performance']
title='Improve list() pre-sizing for inputs with known lengths'updated_at=<Date2020-03-07.09:22:57.549>user='https://github.com/rhettinger'
The list() constructor isn't taking full advantage of known input lengths or length hints. Ideally, it should pre-size and not over-allocate when the input size is known or can be reasonably estimated.
Python 3.8.0a0 (heads/master:091e95e900, Apr 5 2018, 09:48:33)
[Clang 9.1.0 (clang-902.0.39.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from sys import getsizeof
>>> getsizeof([0] *10)
144
>>> getsizeof(list([0] *10))
200
>>> getsizeof(list(range(10)))
200
Calling PyObject_LengthHint() adds an overhead. It is significant for short sequences. I work on a patch that reduces it. PR 6493 adds the second call of PyObject_LengthHint() and increases the overhead.
As for this issue, in-place repeat overallocates too.
>>> a = [0]; a *=10; getsizeof(a)
200
I think it would be better to make it not preallocating.
And maybe it would be worth to avoid overallocating if newsize > allocated + allocated/8 or something like.
Should we shrink the list of the length hint was way too big? For example, if the length hint was 100 but the final list of only 10. Should we shrink in that case?
I'm asking because it seems like Pablo's PR doesn't shrink the list in that case.
I wasn't sure so I checked, del shrinks the list if needed:
@serhiy.storchaka @rhettinger@vstinner Should we better make the pre-allocation if the length of the iterable is known (so we call PyObject_Length and not PyObject_LengthHint)? This will keep the logic simpler (so not shrinking if PyObject_LengthHint gives more than the real length) and it will not be as expensive as calling PyObject_LengthHint.
New changeset e182318 by Miss Islington (bot) (Raymond Hettinger) in branch 'master': bpo-33234: Add another attribution in Whatsnew (GH-11899) e182318
Activity
rhettinger commentedon Apr 5, 2018
The list() constructor isn't taking full advantage of known input lengths or length hints. Ideally, it should pre-size and not over-allocate when the input size is known or can be reasonably estimated.
serhiy-storchaka commentedon Apr 17, 2018
Calling PyObject_LengthHint() adds an overhead. It is significant for short sequences. I work on a patch that reduces it. PR 6493 adds the second call of PyObject_LengthHint() and increases the overhead.
As for this issue, in-place repeat overallocates too.
I think it would be better to make it not preallocating.
And maybe it would be worth to avoid overallocating if newsize > allocated + allocated/8 or something like.
pablogsal commentedon Apr 17, 2018
Microbenchmarked with @vstinner's perf module:
python -m perf timeit "list([0]*10)" -o new.json
checkout master and build
python -m perf timeit "list([0]*10)" -o old.json
python -m perf compare_to new.json old.json
Mean +- std dev: [new] 241 ns +- 3 ns -> [old] 243 ns +- 18 ns: 1.01x slower (+1%)
Not significant!
vstinner commentedon Apr 30, 2018
See also http://bugs.python.org/issue26814#msg264003 and bpo-26828.
vstinner commentedon Apr 30, 2018
Should we shrink the list of the length hint was way too big? For example, if the length hint was 100 but the final list of only 10. Should we shrink in that case?
I'm asking because it seems like Pablo's PR doesn't shrink the list in that case.
I wasn't sure so I checked, del shrinks the list if needed:
pablogsal commentedon Apr 30, 2018
@serhiy.storchaka @rhettinger @vstinner Should we better make the pre-allocation if the length of the iterable is known (so we call PyObject_Length and not PyObject_LengthHint)? This will keep the logic simpler (so not shrinking if PyObject_LengthHint gives more than the real length) and it will not be as expensive as calling PyObject_LengthHint.
pablogsal commentedon Oct 28, 2018
New changeset 372d705 by Pablo Galindo in branch 'master':
bpo-33234 Improve list() pre-sizing for inputs with known lengths (GH-9846)
372d705
vstinner commentedon Oct 28, 2018
Oh. Can you please document the optimization in the following doc as well?
https://docs.python.org/dev/whatsnew/3.8.html#optimizations
pablogsal commentedon Oct 28, 2018
Sure! Opened #10200 to address that. :)
pablogsal commentedon Oct 28, 2018
New changeset c61e229 by Pablo Galindo in branch 'master':
bpo-33234: Add exact allocation optimization to lists in What's New (GH-10200)
c61e229
pablogsal commentedon Dec 29, 2018
New changeset 0e5f771 by Pablo Galindo (Sergey Fedoseev) in branch 'master':
bpo-33234: Simplify list_preallocate_exact() (GH-11220)
0e5f771
miss-islington commentedon Feb 16, 2019
New changeset e182318 by Miss Islington (bot) (Raymond Hettinger) in branch 'master':
bpo-33234: Add another attribution in Whatsnew (GH-11899)
e182318
ericsnowcurrently commentedon Mar 2, 2020
Possible backward incompatibility caused by this issue: bpo-39829
vstinner commentedon Mar 7, 2020
See also bpo-14126: "Speed up list comprehensions by preallocating the list where possible".