GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Update `list()` to use the existing freelist · Issue #160858 · python/cpython Closed Labels interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagePerformance or resource usagetype-featureA feature request or enhancementA feature request or enhancement DescriptionFeature or enhancement
I found this while profiling builtin constructor calls with callgrind (instructions per function). For Microbenchmarks (pyperf, PGO+LTO, Linux x86-64, interleaved A/B, main vs patch):
Untouched controls ( Benchmark scriptimport pyperf runner = pyperf.Runner() for stmt in ["list()", "list(t)", "list(l)", "list(r)", "list(d)", "L(t)", "[]", "len(l)", "l[0]", "x + 1", "tuple(l)"]: runner.timeit(stmt, stmt, "t = (1, 2, 3); l = [1, 2, 3]; r = range(3); d = dict.fromkeys(t); x = 12345\n" "class L(list): pass") ./python bm_list.py --affinity=10-13 -o main.json # on main ./python bm_list.py --affinity=10-13 -o patch.json # on the patch python -m pyperf compare_to main.json patch.json --table -G Runs were interleaved (main, patch, main, patch) on PGO+LTO builds. pystats:
|
| statement | main: allocations / from freelist | patch: allocations / from freelist |
|---|---|---|
list() |
100,001 / 98,978 | 1 / 198,978 |
list(t) |
200,001 / 98,978 | 100,001 / 198,978 |
[] |
1 / 198,978 | 1 / 198,978 |
After warm-up, every list() object comes from the freelist, as with [].
The remaining allocation in list(t) is the item array.
list_vectorcall() was added in bpo-37207: Use vertorcall for list() #18928 and kept using the existing generic alloc.This is a minor feature, which does not need previous discussion elsewhere
No response