Commit 818f1f4
authored
Optimize TreeSitterAnalyzer.find_functions
The optimization achieves a **27% runtime improvement** (18.2ms → 14.3ms) by making two key changes to the tree traversal logic:
## Primary Optimization: Iterative DFS with Explicit Stack
The original code used Python recursion to traverse the syntax tree, making a recursive call for each child node. This approach incurs significant overhead from:
- Python's function call machinery (stack frame creation, argument passing)
- Repeated keyword argument unpacking on every recursive call
- Deep call stacks for nested code structures
The optimized version replaces recursion with an **iterative depth-first search using an explicit stack**. Each stack entry stores `(node, current_class, current_function)` as a tuple, and the traversal loop pops nodes and processes them iteratively. This eliminates function call overhead entirely and reduces memory pressure from deep recursion.
**Impact on workloads**: The line profiler shows the `_walk_tree_for_functions` method dropped from 70ms to 42ms (40% improvement). Test results confirm larger speedups for deeply nested code:
- 50 levels of nesting: **37.3% faster** (974μs → 709μs)
- 100 functions: **25.4% faster** (1.33ms → 1.06ms)
- Large source files with mixed content: **32.6% faster** (2.62ms → 1.97ms)
## Secondary Optimization: Cached Function Type Sets
The original code reconstructed the `function_types` set on every node visit (12,665 times in profiling), repeatedly adding "arrow_function" and "method_definition" based on flags. The optimized version caches these sets in `_function_types_cache` keyed by `(include_methods, include_arrow_functions)`. Since these flags are constant per traversal, the set is built once and reused for all nodes.
**Impact**: While a smaller contributor than the iterative traversal, this eliminates ~20ms of redundant set operations visible in the line profiler (lines building and modifying `function_types` accounted for ~15% of original runtime).
## Trade-offs
For very small/empty inputs, the optimization shows minor slowdowns (7-10% on empty source, whitespace-only files) due to cache initialization overhead. However, these edge cases are not representative of real-world usage where the function analyzes actual code with multiple functions. All realistic test cases with actual functions show speedups of **8-42%**, with the largest gains on complex, deeply nested, or large codebases—exactly the scenarios where this analyzer would be used in production.
The optimization maintains identical behavior and correctness across all 54 test cases while dramatically improving performance for production workloads.1 parent 2832845 commit 818f1f4
1 file changed
Lines changed: 65 additions & 54 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
140 | 140 | | |
141 | 141 | | |
142 | 142 | | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
143 | 146 | | |
144 | 147 | | |
145 | 148 | | |
| |||
219 | 222 | | |
220 | 223 | | |
221 | 224 | | |
222 | | - | |
223 | | - | |
224 | | - | |
225 | | - | |
226 | | - | |
227 | | - | |
228 | | - | |
229 | | - | |
230 | | - | |
231 | | - | |
232 | | - | |
233 | | - | |
234 | | - | |
235 | | - | |
236 | | - | |
237 | | - | |
238 | | - | |
239 | | - | |
240 | | - | |
241 | | - | |
242 | | - | |
243 | | - | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
244 | 258 | | |
245 | | - | |
246 | | - | |
| 259 | + | |
| 260 | + | |
247 | 261 | | |
248 | | - | |
249 | | - | |
250 | | - | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
251 | 265 | | |
252 | | - | |
253 | | - | |
| 266 | + | |
| 267 | + | |
254 | 268 | | |
255 | | - | |
256 | | - | |
| 269 | + | |
| 270 | + | |
257 | 271 | | |
258 | | - | |
259 | | - | |
| 272 | + | |
| 273 | + | |
260 | 274 | | |
261 | | - | |
262 | | - | |
263 | | - | |
264 | | - | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
265 | 280 | | |
266 | | - | |
267 | | - | |
| 281 | + | |
| 282 | + | |
268 | 283 | | |
269 | | - | |
270 | | - | |
271 | | - | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
272 | 287 | | |
273 | | - | |
274 | | - | |
275 | | - | |
276 | | - | |
277 | | - | |
278 | | - | |
279 | | - | |
280 | | - | |
281 | | - | |
282 | | - | |
283 | | - | |
284 | | - | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
285 | 296 | | |
286 | 297 | | |
287 | 298 | | |
| |||
0 commit comments