Commit b54dfca
authored
Optimize detect_unused_helper_functions
This optimization achieves a **14% runtime improvement** (4.80ms → 4.19ms) through several targeted micro-optimizations that reduce overhead in hot code paths:
## Key Performance Improvements
### 1. **Eliminated Redundant Dictionary Lookups via Caching**
In `CodeStringsMarkdown` properties (`flat`, `file_to_path`), the original code called `self._cache.get("key")` twice per invocation. The optimized version caches the result in a local variable:
```python
# Before: two lookups
if self._cache.get("flat") is not None:
return self._cache["flat"]
# After: one lookup
cached = self._cache.get("flat")
if cached is not None:
return cached
```
This eliminates redundant hash table lookups in frequently accessed properties.
### 2. **Replaced `dict.setdefault()` for Atomic List Operations**
In `_analyze_imports_in_optimized_code`, the original code used an if-check followed by assignment for the helpers dictionary:
```python
# Before: check + assign (two operations)
if func_name in file_entry:
file_entry[func_name].append(helper)
else:
file_entry[func_name] = [helper]
# After: single atomic operation
helpers_by_file_and_func[module_name].setdefault(func_name, []).append(helper)
```
The `setdefault()` approach reduces the operation to a single dictionary call, eliminating the membership test.
### 3. **Hoisted `as_posix()` Calls Outside String Formatting**
In the `markdown` property, path conversion was moved outside the f-string:
```python
# Before: as_posix() called inside f-string
f"```python:{code_string.file_path.as_posix()}\n..."
# After: precomputed in conditional branch
if code_string.file_path:
file_path_str = code_string.file_path.as_posix()
result.append(f"```python:{file_path_str}\n...")
```
This avoids repeated method calls during string formatting.
### 4. **Optimized Set Membership Tests with Early Exit**
The most impactful change replaced `set.intersection()` with short-circuit boolean checks:
```python
# Before: creates intermediate set via intersection
is_called = bool(possible_call_names.intersection(called_function_names))
# After: early-exit on first match
if (helper_qualified_name in called_function_names or
helper_simple_name in called_function_names or
helper_fully_qualified_name in called_function_names):
is_called = True
```
With ~200 helpers in large-scale tests, this avoids creating temporary sets for every comparison, showing **50% speedup** in the large helper test (1.31ms → 868μs).
### 5. **Minimized Repeated Attribute Access**
Variables like `entrypoint_file_path`, `attr_name`, and `value_id` are now cached before use, reducing attribute lookups in the AST traversal loop.
## Impact Based on Test Results
- **Small workloads** (10-50 helpers): 10-16% speedup from reduced dict lookups
- **Large workloads** (200 helpers): 50% speedup due to eliminated set operations in the helper-checking loop
- **Edge cases** (syntax errors, missing functions): Minimal overhead, consistent 2-3% improvement
This optimization is particularly valuable when `detect_unused_helper_functions` is called repeatedly during code analysis pipelines, as the cumulative effect of these micro-optimizations scales with the number of helper functions and code blocks analyzed.1 parent 65ff392 commit b54dfca
1 file changed
Lines changed: 43 additions & 39 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
634 | 634 | | |
635 | 635 | | |
636 | 636 | | |
637 | | - | |
638 | | - | |
639 | | - | |
640 | | - | |
641 | | - | |
| 637 | + | |
642 | 638 | | |
643 | 639 | | |
644 | | - | |
645 | | - | |
646 | | - | |
647 | | - | |
648 | 640 | | |
649 | 641 | | |
650 | 642 | | |
651 | 643 | | |
652 | 644 | | |
653 | | - | |
| 645 | + | |
654 | 646 | | |
655 | 647 | | |
656 | 648 | | |
657 | 649 | | |
658 | | - | |
| 650 | + | |
659 | 651 | | |
| 652 | + | |
660 | 653 | | |
661 | | - | |
662 | | - | |
| 654 | + | |
| 655 | + | |
663 | 656 | | |
664 | 657 | | |
665 | 658 | | |
666 | 659 | | |
667 | 660 | | |
668 | 661 | | |
669 | | - | |
670 | | - | |
671 | | - | |
672 | | - | |
673 | | - | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
674 | 671 | | |
675 | 672 | | |
676 | 673 | | |
| |||
750 | 747 | | |
751 | 748 | | |
752 | 749 | | |
753 | | - | |
754 | | - | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
755 | 753 | | |
756 | 754 | | |
757 | 755 | | |
758 | | - | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
759 | 759 | | |
760 | | - | |
| 760 | + | |
| 761 | + | |
761 | 762 | | |
762 | 763 | | |
763 | 764 | | |
764 | | - | |
| 765 | + | |
765 | 766 | | |
766 | | - | |
767 | | - | |
768 | 767 | | |
769 | | - | |
| 768 | + | |
| 769 | + | |
770 | 770 | | |
771 | | - | |
772 | | - | |
773 | | - | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
774 | 775 | | |
775 | 776 | | |
776 | 777 | | |
| |||
780 | 781 | | |
781 | 782 | | |
782 | 783 | | |
| 784 | + | |
783 | 785 | | |
784 | 786 | | |
785 | 787 | | |
786 | 788 | | |
787 | 789 | | |
788 | 790 | | |
789 | 791 | | |
790 | | - | |
791 | | - | |
792 | | - | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
793 | 799 | | |
794 | | - | |
| 800 | + | |
795 | 801 | | |
796 | 802 | | |
797 | | - | |
798 | | - | |
799 | | - | |
800 | | - | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
801 | 807 | | |
802 | 808 | | |
803 | 809 | | |
804 | 810 | | |
805 | | - | |
806 | 811 | | |
807 | 812 | | |
808 | | - | |
809 | 813 | | |
810 | 814 | | |
811 | 815 | | |
| |||
0 commit comments