| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
Benchmarks are good: from pyperf import Runner, perf_counter
def bench_listcomp(loops, length):
src = list(map(float, range(length)))
t0 = perf_counter()
for i in range(loops):
[x for x in src]
return perf_counter() - t0
def bench_append(loops, length):
src = list(map(float, range(length)))
t0 = perf_counter()
for i in range(loops):
arr = []
for x in src:
arr.append(x)
return perf_counter() - t0
runner = Runner()
for n in [100, 1_000, 10_000, 100_000]:
runner.bench_time_func(f"listcomp {n}", bench_listcomp, n)
runner.bench_time_func(f"append {n}", bench_append, n)Results from GCC on WSL with --enable-optimizations --with-lto Faster (8): - listcomp 10000: 118 us +- 2 us -> 92.6 us +- 1.5 us: 1.28x faster - listcomp 100000: 1.16 ms +- 0.02 ms -> 916 us +- 26 us: 1.27x faster - listcomp 1000: 12.3 us +- 0.2 us -> 9.89 us +- 0.41 us: 1.25x faster - listcomp 100: 1.59 us +- 0.03 us -> 1.32 us +- 0.05 us: 1.21x faster - append 100000: 1.69 ms +- 0.05 ms -> 1.45 ms +- 0.04 ms: 1.17x faster - append 10000: 168 us +- 4 us -> 145 us +- 3 us: 1.16x faster - append 1000: 17.4 us +- 0.3 us -> 15.2 us +- 0.6 us: 1.14x faster - append 100: 2.03 us +- 0.06 us -> 1.81 us +- 0.08 us: 1.12x faster Geometric mean: 1.20x faster |
Sorry, something went wrong.
There was a problem hiding this comment.
I think this would be simpler, and just as fast, by renaming app1 to _PyList_AppendTakeRef (with appropriate refcount adjustments).
No need for the inline functions.
Sorry, something went wrong.
| PyAPI_FUNC(int) | ||
| _PyList_AppendTakeRefListResize(PyListObject *self, PyObject *newitem); | ||
|
|
||
| static inline int |
There was a problem hiding this comment.
No need for an inline function.
Let the LTO pass decide if it wants to inline it.
Sorry, something went wrong.
| app1(PyListObject *self, PyObject *v) | ||
| /* internal, used by _PyList_AppendTakeRef */ | ||
| int | ||
| _PyList_AppendTakeRefListResize(PyListObject *self, PyObject *newitem) |
There was a problem hiding this comment.
Do we need the extra function?
Converting app1 to _PyList_AppendTakeRef would seem to be enough.
Sorry, something went wrong.
There was a problem hiding this comment.
I tried something like that and the results are on the bpo issue, but it seems there is a significant benefit to having the separate as-small-as-possible function that always gets inlined as opposed to a slightly longer version that we let the compiler figure out.
Sorry, something went wrong.
There was a problem hiding this comment.
Presumably the compiler isn't inlining the function because it isn't hot enough.
PRECALL_NO_KW_LIST_APPEND and LIST_APPEND are only 0.3% of all instructions executed, so maybe it is best not to inline.
Do you have benchmark numbers for the standard suite?
Sorry, something went wrong.
There was a problem hiding this comment.
https://gist.github.com/sweeneyde/6cbbe1c9d216d117370a809c704b6cfc
Geometric mean: 1.00x faster
Sorry, something went wrong.
There was a problem hiding this comment.
Also, IMO there is a relative lack of list comprehensions in the pyperformance suite.
Sorry, something went wrong.
|
@markshannon Since pyperformance results were negligible and this has a significant speedup on operations that live in hot loops (albeit not in pyperformance), is it okay if I merge this? |
Sorry, something went wrong.
|
Sorry, this dropped off my radar. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
https://bugs.python.org/issue47009