Commit 73584bc
authored
Optimize JavaScriptSupport._extract_types_from_definition
The optimized code achieves a **1617% speedup** (4.49ms → 261μs) through two key optimizations:
## Primary Optimization: Iterative Tree Traversal
The original code used recursive function calls via `walk_for_types(node)` to traverse the AST. The optimized version replaces this with an iterative stack-based approach:
**Original (Recursive):**
```python
def walk_for_types(node: Any) -> None:
if node.type == "type_identifier":
# process node
for child in node.children:
walk_for_types(child) # Recursive call per child
```
**Optimized (Iterative):**
```python
stack = [tree.root_node]
while stack:
node = stack.pop()
if node.type == "type_identifier":
# process node
if node.children:
stack.extend(node.children)
```
**Why this is faster:**
- **Eliminates function call overhead**: Each recursive call creates a new stack frame with parameter passing, local variable setup, and return handling. In the line profiler, the original `walk_for_types` call consumed 60.1% of total time (6.97ms).
- **Reduces memory allocations**: Recursive calls allocate stack frames for each node visited. The iterative approach reuses a single list (`stack`) that grows and shrinks as needed.
- **Better cache locality**: The iterative approach keeps the processing loop tight and localized, improving CPU instruction cache utilization.
The test results confirm this optimization is effective across all scenarios:
- Large-scale test (1000 types): 343μs → 241μs (42.1% faster)
- Nested structures test: 5.72μs → 5.47μs (4.59% faster)
- Basic extraction: 5.97μs → 4.61μs (29.6% faster)
## Secondary Optimization: Lazy Parser Initialization
The optimized code adds a `@property` decorator for `parser` that lazily creates and caches the Parser instance:
```python
@Property
def parser(self) -> Parser:
if self._parser is None:
self._parser = Parser()
return self._parser
```
This ensures the Parser is only created when first accessed and reused thereafter, avoiding redundant object construction if the analyzer is instantiated but parse is never called, or if it's called multiple times.
## Performance Impact
The combination of these optimizations particularly benefits workloads with:
- **Deep or wide AST structures**: The iterative approach scales linearly without stack depth concerns
- **Repeated type extraction calls**: The cached parser amortizes initialization cost
- **Large codebases**: As seen in the 1000-type test, the speedup amplifies with scale (42% improvement)
The optimizations maintain identical behavior and APIs while delivering substantial runtime improvements across all test cases, making type extraction significantly more efficient for JavaScript/TypeScript code analysis workflows.1 parent feca98d commit 73584bc
2 files changed
Lines changed: 26 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1011 | 1011 | | |
1012 | 1012 | | |
1013 | 1013 | | |
1014 | | - | |
| 1014 | + | |
| 1015 | + | |
| 1016 | + | |
| 1017 | + | |
| 1018 | + | |
| 1019 | + | |
1015 | 1020 | | |
1016 | 1021 | | |
1017 | 1022 | | |
1018 | 1023 | | |
1019 | 1024 | | |
1020 | 1025 | | |
1021 | | - | |
1022 | | - | |
| 1026 | + | |
| 1027 | + | |
| 1028 | + | |
| 1029 | + | |
| 1030 | + | |
1023 | 1031 | | |
1024 | | - | |
1025 | 1032 | | |
1026 | 1033 | | |
1027 | 1034 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1772 | 1772 | | |
1773 | 1773 | | |
1774 | 1774 | | |
| 1775 | + | |
| 1776 | + | |
| 1777 | + | |
| 1778 | + | |
| 1779 | + | |
| 1780 | + | |
| 1781 | + | |
| 1782 | + | |
| 1783 | + | |
| 1784 | + | |
| 1785 | + | |
| 1786 | + | |
| 1787 | + | |
| 1788 | + | |
| 1789 | + | |
1775 | 1790 | | |
1776 | 1791 | | |
1777 | 1792 | | |
| |||
0 commit comments