Skip to content

gh-156860: Fix exponential asyncio.print_call_graph() output - #156861

Open
deadlovelll wants to merge 2 commits into
python:mainfrom
deadlovelll:gh-156860-graph
Open

gh-156860: Fix exponential asyncio.print_call_graph() output#156861
deadlovelll wants to merge 2 commits into
python:mainfrom
deadlovelll:gh-156860-graph

Conversation

@deadlovelll

Copy link
Copy Markdown
Contributor

Fix exponential asyncio.print_call_graph() output

For more details see gh-156860

@brittanyrey

Copy link
Copy Markdown
Contributor

Do you have a benchmark + perf outputs to demonstrate that the actual impact matches the expected impact laid out in the issue?

@deadlovelll

Copy link
Copy Markdown
Contributor Author

Do you have a benchmark + perf outputs to demonstrate that the actual impact matches the expected impact laid out in the issue?

Hi! I'll send it within the day

@deadlovelll

Copy link
Copy Markdown
Contributor Author

@brittanyrey hi again! Here it is

import asyncio
import pyperf

async def waits_for(*deps):
    await asyncio.gather(*deps)

async def build(shape, ntasks):
    fut = asyncio.Future()
    match shape:
        case "chain":
            cur = fut
            for _ in range(ntasks):
                cur = asyncio.ensure_future(waits_for(cur))
        case "dag":
            layer = [fut]
            for _ in range(ntasks // 2):
                layer = [asyncio.ensure_future(waits_for(*layer)) for _ in range(2)]
    await asyncio.sleep(0)
    return fut

def bench(loops, fut):
    t0 = pyperf.perf_counter()
    for _ in range(loops):
        asyncio.format_call_graph(fut)
    return pyperf.perf_counter() - t0

ssz = {
    "chain": (10, 20, 30, 40, 50),
    "dag": (4, 8, 12, 16, 20),
}

if __name__ == "__main__":
    runner = pyperf.Runner()
    for shape, sizes in ssz.items():
        for ntasks in sizes:
            loop = asyncio.new_event_loop()
            fut = loop.run_until_complete(build(shape, ntasks))
            runner.bench_time_func(f"{shape}-{ntasks}", bench, fut)
+----------------+---------+------------------------+
| Benchmark      | before  | after                  |
+================+=========+========================+
| chain-10       | 21.7 us | 22.5 us: 1.04x slower  |
+----------------+---------+------------------------+
| chain-20       | 42.3 us | 44.3 us: 1.05x slower  |
+----------------+---------+------------------------+
| chain-30       | 64.4 us | 67.6 us: 1.05x slower  |
+----------------+---------+------------------------+
| chain-40       | 85.6 us | 89.5 us: 1.05x slower  |
+----------------+---------+------------------------+
| chain-50       | 108 us  | 113 us: 1.04x slower   |
+----------------+---------+------------------------+
| dag-4          | 12.7 us | 13.0 us: 1.03x slower  |
+----------------+---------+------------------------+
| dag-8          | 58.7 us | 29.2 us: 2.01x faster  |
+----------------+---------+------------------------+
| dag-12         | 242 us  | 45.1 us: 5.37x faster  |
+----------------+---------+------------------------+
| dag-16         | 974 us  | 61.4 us: 15.87x faster |
+----------------+---------+------------------------+
| dag-20         | 4.21 ms | 78.1 us: 53.85x faster |
+----------------+---------+------------------------+
| Geometric mean | (ref)   | 2.43x faster           |
+----------------+---------+------------------------+

The regression 3-5% not in the noise range, I thought about not using id() for memo, and got the results:

+----------------+---------+------------------------+
| Benchmark      | before  | after                  |
+================+=========+========================+
| chain-10       | 21.6 us | 22.0 us: 1.02x slower  |
+----------------+---------+------------------------+
| chain-20       | 42.4 us | 43.3 us: 1.02x slower  |
+----------------+---------+------------------------+
| chain-30       | 64.3 us | 65.5 us: 1.02x slower  |
+----------------+---------+------------------------+
| chain-40       | 85.9 us | 87.1 us: 1.01x slower  |
+----------------+---------+------------------------+
| chain-50       | 108 us  | 110 us: 1.01x slower   |
+----------------+---------+------------------------+
| dag-4          | 12.7 us | 12.8 us: 1.01x slower  |
+----------------+---------+------------------------+
| dag-8          | 58.9 us | 28.7 us: 2.05x faster  |
+----------------+---------+------------------------+
| dag-12         | 242 us  | 44.2 us: 5.48x faster  |
+----------------+---------+------------------------+
| dag-16         | 972 us  | 60.0 us: 16.20x faster |
+----------------+---------+------------------------+
| dag-20         | 4.21 ms | 76.5 us: 55.10x faster |
+----------------+---------+------------------------+
| Geometric mean | (ref)   | 2.49x faster           |
+----------------+---------+------------------------+

Now it's 1-2%, and it doesn't grow with size

Thank you for the direction! I already pushed that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants