Skip to content

⚡ Bolt: Optimize AST traversal in iter_calls_in_function_body#104

Open
tachyon-beep wants to merge 1 commit into
mainfrom
bolt-ast-optimization-5446766970559159815
Open

⚡ Bolt: Optimize AST traversal in iter_calls_in_function_body#104
tachyon-beep wants to merge 1 commit into
mainfrom
bolt-ast-optimization-5446766970559159815

Conversation

@tachyon-beep

Copy link
Copy Markdown
Collaborator

💡 What: Replaced the recursive yield from traversal logic in iter_calls_in_function_body with an explicit stack-based iteration using yield and reversed().

🎯 Why: In Python, yield from recursion incurs significant overhead due to the constant creation of generator frames. For hot-path tree traversal tasks like this static analyzer, an explicit stack reduces latency while preserving the original depth-first left-to-right visit order.

📊 Impact: A micro-benchmark showed an expected reduction in execution time of ~25% for function body call discovery.

🔬 Measurement: Verified by running a synthetic test tree benchmark and observing the time drop from ~0.35s to ~0.27s (10,000 iterations). Passed the full test suite (uv run pytest) and verified deterministic output order.


PR created automatically by Jules for task 5446766970559159815 started by @tachyon-beep

Refactored `iter_calls_in_function_body` in `src/wardline/scanner/ast_primitives.py` to use an explicit stack instead of recursive `yield from` generator logic, significantly reducing overhead during hot-path execution. Traversal order is perfectly maintained using `reversed()` and specific skip behavior for nested scopes is fully preserved.

Co-authored-by: tachyon-beep <544926+tachyon-beep@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

Copilot AI review requested due to automatic review settings July 12, 2026 16:13

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes iter_calls_in_function_body in src/wardline/scanner/ast_primitives.py by replacing the recursive yield from traversal with an explicit stack-based DFS, aiming to reduce generator-frame overhead in a hot-path AST walk while preserving traversal order and scope boundaries.

Changes:

  • Reworked iter_calls_in_function_body to use an explicit LIFO stack and reversed child pushing to maintain depth-first, left-to-right visitation order.
  • Updated the golden corpus metadata reason string to reflect the traversal optimization.
  • Added a Jules “bolt” note documenting the optimization rationale and guidance.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/wardline/scanner/ast_primitives.py Replaces recursive generator-based AST traversal with an explicit stack to improve performance while keeping scope-stopping behavior.
tests/golden/identity/corpus/META.json Updates golden corpus metadata “reason” to match the change rationale.
.jules/bolt.md Documents the traversal optimization and intended best practice for similar hot-path routines.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +113 to +114
# Push in reverse order so they are popped in normal order:
# kw_defaults, defaults, decorators
Comment thread .jules/bolt.md
@@ -0,0 +1,3 @@
## 2024-07-12 - Explicit Stack-Based AST Traversal Optimization
**Learning:** In hot-path AST traversal methods like `iter_calls_in_function_body`, relying on recursive `yield from` logic incurs considerable overhead in Python due to the creation of many generator frames. Iterating over `_fields` with a custom explicit stack combined with `yield` removes this generator overhead and provides a measurable performance boost. Avoiding `list.append` for deep trees when early matches exist preserves lazy evaluation. Also, it is necessary to traverse in `reversed()` order when pushing to the stack to retain the original depth-first left-to-right order. When checking dynamic fields via `getattr`, it is critical to retain `isinstance(node, ast.AST)` checks since some fields may be strings or literals (avoiding `AttributeError`).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants