Commit 39ab73d
authored
Optimize _add_timing_instrumentation
The optimized code achieves a **103% speedup** (126ms → 62.2ms) by replacing an expensive O(n²) byte concatenation pattern with an efficient O(n) segment-based approach.
**Key Optimization:**
The original code assembled the instrumented source using repeated immutable byte concatenation in reverse order:
```python
for start, end, new_bytes in sorted(replacements, key=lambda item: item[0], reverse=True):
updated = updated[:start] + new_bytes + updated[end:]
```
This pattern consumed **76.7% of total execution time** because each concatenation creates a new bytes object, copying all existing data. With 1,340 replacements per test run, this quadratic behavior dominated performance.
The optimized version builds a list of byte segments and joins them once:
```python
segments: list[bytes] = []
prev_end = 0
for start, end, new_bytes in sorted(replacements, key=lambda item: item[0]):
segments.append(source_bytes[prev_end:start])
segments.append(new_bytes)
prev_end = end
segments.append(source_bytes[prev_end:])
updated = b"".join(segments)
```
This reduces the replacement loop from 447ms to ~1ms (447× faster for this section), accounting for the majority of the overall 2× speedup.
**Why This Works:**
1. **Linear memory copies**: Each byte range is copied exactly once into the segment list
2. **Single final join**: `b"".join()` allocates the exact final size and copies each segment once
3. **Forward iteration**: Eliminates the need for reverse sorting and repeated slicing operations
**Impact on Workloads:**
Based on the test results and function references, this optimization is particularly effective for:
- **Large-scale instrumentation**: The `test_performance_with_massive_call_count` (1000 @test methods) shows a **176% speedup** (97.4ms → 35.3ms)
- **Files with many test methods**: `test_many_test_methods_with_calls` (200 methods) achieves **23.3% speedup**
- **Files with many statements**: `test_large_number_of_statements_is_handled_quickly_and_correctly` benefits from the reduced per-replacement overhead
The function is called during Java test instrumentation for JIT warmup timing, so this speedup directly reduces the overhead of preparing performance benchmarks in the hot path of the Codeflash workflow.1 parent 32bac21 commit 39ab73d
1 file changed
Lines changed: 8 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1235 | 1235 | | |
1236 | 1236 | | |
1237 | 1237 | | |
1238 | | - | |
1239 | | - | |
1240 | | - | |
| 1238 | + | |
| 1239 | + | |
| 1240 | + | |
| 1241 | + | |
| 1242 | + | |
| 1243 | + | |
| 1244 | + | |
| 1245 | + | |
1241 | 1246 | | |
1242 | 1247 | | |
1243 | 1248 | | |
| |||
0 commit comments