GH-96793: Specialize FOR_ITER for generators.#98772
Conversation
|
There is a bug in this. It doesn't set the |
Sorry, something went wrong.
|
https://github.com/python/cpython/compare/main...faster-cpython:cpython:specialize-for-iter-gen-handle-exc-stack?expand=1 |
Sorry, something went wrong.
You can run https://github.com/python/pyperformance/blob/main/pyperformance/data-files/benchmarks/bm_generators/run_benchmark.py, it is specifically designed to benchmark generators (microbenchmark). |
Sorry, something went wrong.
|
I'll run that benchmark if pyperformance ever does another release. |
Sorry, something went wrong.
|
I'm seeing a 35% speedup on this benchmark: Tree iteratorimport timeit
class Tree:
def __init__(self, left, value, right):
self.left = left
self.value = value
self.right = right
def __iter__(self):
if self.left:
for item in self.left:
yield item
yield self.value
if self.right:
for item in self.right:
yield item
def tree(input: range) -> Tree | None:
n = len(input)
if n == 0:
return None
i = n // 2
return Tree(tree(input[:i]), input[i], tree(input[i + 1:]))
def setup():
global iterable
assert list(tree(range(10))) == list(range(10))
iterable = tree(range(100000))
print(timeit.timeit("for _ in iterable: pass", "setup()", globals=globals(), number=10))Note that this uses And a 36% speedup on this one: Flat iteratorimport timeit
class RangeWrapper:
def __init__(self, n):
self.r = range(n)
def __iter__(self):
for item in self.r:
yield item
def setup():
global iterable
iterable = RangeWrapper(1000000)
print(timeit.timeit("for _ in iterable: pass", "setup()", globals=globals(), number=10))Comparing the fastest of 6 runs for main and this PR. |
Sorry, something went wrong.
Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>
Performance results seem to be just noise. I suspect there aren't enough uses of generators in the benchmark suite for this to make a difference.
for gen():, and awaiting coroutines,await coro()#96793