Skip to content

Comments

⚡️ Speed up function _byte_to_line_index by 41% in PR #1580 (fix/java-direct-jvm-and-bugs)#1586

Merged
claude[bot] merged 2 commits intofix/java-direct-jvm-and-bugsfrom
codeflash/optimize-pr1580-2026-02-20T06.34.48
Feb 20, 2026
Merged

⚡️ Speed up function _byte_to_line_index by 41% in PR #1580 (fix/java-direct-jvm-and-bugs)#1586
claude[bot] merged 2 commits intofix/java-direct-jvm-and-bugsfrom
codeflash/optimize-pr1580-2026-02-20T06.34.48

Conversation

@codeflash-ai
Copy link
Contributor

@codeflash-ai codeflash-ai bot commented Feb 20, 2026

⚡️ This pull request contains optimizations for PR #1580

If you approve this dependent PR, these changes will be merged into the original PR branch fix/java-direct-jvm-and-bugs.

This PR will be automatically closed if the original PR is merged.


📄 41% (0.41x) speedup for _byte_to_line_index in codeflash/languages/java/instrumentation.py

⏱️ Runtime : 584 microseconds 415 microseconds (best of 165 runs)

📝 Explanation and details

The main optimization here is eliminating the max(0, idx) call by handling the edge case directly. Since bisect_right returns 0 when byte_offset is less than all elements, subtracting 1 gives -1, which we can catch with a simple comparison. This avoids the function call overhead of max().

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 1637 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Click to see Generated Regression Tests
import bisect

# imports
import pytest
from codeflash.languages.java.instrumentation import _byte_to_line_index

def test_basic_single_line_start():
    """Test byte offset at the very beginning of a single-line document."""
    # byte_offset=0 should map to line index 0
    line_byte_starts = [0]
    codeflash_output = _byte_to_line_index(0, line_byte_starts); result = codeflash_output # 1.29μs -> 762ns (69.6% faster)

def test_basic_multiple_lines_first_line():
    """Test byte offset on the first line of a multi-line document."""
    # byte_offset=5 should map to line 0 when lines start at [0, 10, 20]
    line_byte_starts = [0, 10, 20]
    codeflash_output = _byte_to_line_index(5, line_byte_starts); result = codeflash_output # 1.21μs -> 711ns (70.5% faster)

def test_basic_multiple_lines_second_line():
    """Test byte offset on the second line of a multi-line document."""
    # byte_offset=15 should map to line 1 when lines start at [0, 10, 20]
    line_byte_starts = [0, 10, 20]
    codeflash_output = _byte_to_line_index(15, line_byte_starts); result = codeflash_output # 1.07μs -> 681ns (57.4% faster)

def test_basic_multiple_lines_third_line():
    """Test byte offset on the third line of a multi-line document."""
    # byte_offset=25 should map to line 2 when lines start at [0, 10, 20]
    line_byte_starts = [0, 10, 20]
    codeflash_output = _byte_to_line_index(25, line_byte_starts); result = codeflash_output # 972ns -> 671ns (44.9% faster)

def test_basic_byte_offset_at_line_boundary():
    """Test byte offset exactly at a line boundary."""
    # byte_offset=10 is exactly at the start of line 2
    # bisect_right will place it in the next line's slot, then -1 brings it back
    line_byte_starts = [0, 10, 20]
    codeflash_output = _byte_to_line_index(10, line_byte_starts); result = codeflash_output # 1.04μs -> 752ns (38.6% faster)

def test_basic_large_byte_offset():
    """Test a large byte offset within the document."""
    # byte_offset=95 should map to line 9 when lines are spaced by 10 bytes
    line_byte_starts = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
    codeflash_output = _byte_to_line_index(95, line_byte_starts); result = codeflash_output # 1.02μs -> 731ns (39.8% faster)

def test_edge_empty_line_byte_starts():
    """Test behavior with an empty line_byte_starts list."""
    # bisect_right on empty list returns 0, then -1 gives -1, max(0, -1) = 0
    line_byte_starts = []
    codeflash_output = _byte_to_line_index(0, line_byte_starts); result = codeflash_output # 951ns -> 651ns (46.1% faster)

def test_edge_empty_line_byte_starts_nonzero_offset():
    """Test non-zero byte offset with an empty line_byte_starts list."""
    # Even with non-zero offset, empty list should return 0 due to max(0, idx)
    line_byte_starts = []
    codeflash_output = _byte_to_line_index(100, line_byte_starts); result = codeflash_output # 892ns -> 651ns (37.0% faster)

def test_edge_byte_offset_zero():
    """Test byte offset of 0 with a normal line_byte_starts list."""
    # byte_offset=0 should always map to line 0
    line_byte_starts = [0, 10, 20, 30]
    codeflash_output = _byte_to_line_index(0, line_byte_starts); result = codeflash_output # 1.09μs -> 782ns (39.6% faster)

def test_edge_byte_offset_before_any_line():
    """Test byte offset that is less than the first line start."""
    # If byte_offset < first line start, bisect_right returns 0, then -1, max(0, -1) = 0
    line_byte_starts = [10, 20, 30]
    codeflash_output = _byte_to_line_index(5, line_byte_starts); result = codeflash_output # 1.00μs -> 731ns (37.1% faster)

def test_edge_byte_offset_far_beyond_last_line():
    """Test byte offset far beyond the last line in the list."""
    # byte_offset=1000 should map to the last line (index 4)
    line_byte_starts = [0, 10, 20, 30, 40]
    codeflash_output = _byte_to_line_index(1000, line_byte_starts); result = codeflash_output # 1.02μs -> 652ns (56.7% faster)

def test_edge_single_line_with_nonzero_start():
    """Test a single line that doesn't start at byte 0."""
    # line_byte_starts = [5] means the only line starts at byte 5
    # byte_offset=3 (before the line) should return 0
    line_byte_starts = [5]
    codeflash_output = _byte_to_line_index(3, line_byte_starts); result = codeflash_output # 982ns -> 741ns (32.5% faster)

def test_edge_negative_result_prevented_by_max():
    """Test that max(0, idx) prevents negative results."""
    # With empty list and any offset, bisect_right returns 0, idx becomes -1
    # max(0, -1) ensures we return 0 instead of -1
    line_byte_starts = []
    codeflash_output = _byte_to_line_index(50, line_byte_starts); result = codeflash_output # 872ns -> 611ns (42.7% faster)

def test_edge_consecutive_identical_line_starts():
    """Test handling of duplicate values in line_byte_starts."""
    # Duplicate line starts might occur in malformed data
    line_byte_starts = [0, 10, 10, 20]
    codeflash_output = _byte_to_line_index(10, line_byte_starts); result = codeflash_output # 1.04μs -> 732ns (42.3% faster)

def test_edge_unsorted_line_byte_starts():
    """Test with an unsorted line_byte_starts list (bisect expects sorted)."""
    # bisect behavior on unsorted data is undefined, but shouldn't crash
    line_byte_starts = [0, 20, 10, 30]
    codeflash_output = _byte_to_line_index(15, line_byte_starts); result = codeflash_output # 1.00μs -> 711ns (40.9% faster)

def test_edge_very_large_byte_offset():
    """Test with a very large byte offset."""
    # byte_offset of 10,000,000 should safely map to last line
    line_byte_starts = [0, 100, 200, 300]
    codeflash_output = _byte_to_line_index(10000000, line_byte_starts); result = codeflash_output # 992ns -> 671ns (47.8% faster)

def test_edge_single_element_list_zero():
    """Test with a single-element line_byte_starts list starting at 0."""
    line_byte_starts = [0]
    codeflash_output = _byte_to_line_index(5, line_byte_starts); result = codeflash_output # 1.05μs -> 642ns (63.9% faster)

def test_edge_single_element_list_nonzero():
    """Test with a single-element line_byte_starts list not starting at 0."""
    line_byte_starts = [100]
    codeflash_output = _byte_to_line_index(50, line_byte_starts); result = codeflash_output # 952ns -> 661ns (44.0% faster)

def test_large_scale_many_lines_first_line():
    """Test performance with 1000 lines, byte offset on first line."""
    # Create a list of 1000 line starts at 10-byte intervals
    line_byte_starts = [i * 10 for i in range(1000)]
    codeflash_output = _byte_to_line_index(5, line_byte_starts); result = codeflash_output # 1.27μs -> 892ns (42.7% faster)

def test_large_scale_many_lines_middle_line():
    """Test performance with 1000 lines, byte offset in the middle."""
    # Create a list of 1000 line starts at 10-byte intervals
    line_byte_starts = [i * 10 for i in range(1000)]
    # byte_offset=5000 should map to line ~500
    codeflash_output = _byte_to_line_index(5000, line_byte_starts); result = codeflash_output # 1.25μs -> 912ns (37.3% faster)

def test_large_scale_many_lines_last_line():
    """Test performance with 1000 lines, byte offset on last line."""
    # Create a list of 1000 line starts at 10-byte intervals
    line_byte_starts = [i * 10 for i in range(1000)]
    # byte_offset=9995 should map to the last line (index 999)
    codeflash_output = _byte_to_line_index(9995, line_byte_starts); result = codeflash_output # 1.18μs -> 781ns (51.3% faster)

def test_large_scale_many_lines_beyond_last():
    """Test performance with 1000 lines, byte offset beyond the document."""
    # Create a list of 1000 line starts at 10-byte intervals
    line_byte_starts = [i * 10 for i in range(1000)]
    # byte_offset=100000 far beyond the last line
    codeflash_output = _byte_to_line_index(100000, line_byte_starts); result = codeflash_output # 1.16μs -> 832ns (39.7% faster)

def test_large_scale_variable_line_lengths():
    """Test with 1000 lines of varying byte lengths."""
    # Create line starts with increasing intervals (simulating variable line lengths)
    line_byte_starts = []
    cumulative = 0
    for i in range(1000):
        line_byte_starts.append(cumulative)
        cumulative += (i % 100) + 1  # Line length varies from 1 to 100 bytes
    
    # Test at the beginning
    codeflash_output = _byte_to_line_index(0, line_byte_starts); result_start = codeflash_output # 1.22μs -> 902ns (35.5% faster)
    
    # Test near the middle
    mid_offset = cumulative // 2
    codeflash_output = _byte_to_line_index(mid_offset, line_byte_starts); result_mid = codeflash_output # 761ns -> 550ns (38.4% faster)
    
    # Test near the end
    codeflash_output = _byte_to_line_index(cumulative - 1, line_byte_starts); result_end = codeflash_output # 501ns -> 380ns (31.8% faster)

def test_large_scale_many_offsets_iteration():
    """Test 1000 different byte offsets across a 100-line document."""
    # Create 100 lines
    line_byte_starts = [i * 100 for i in range(100)]
    
    # Test 1000 different byte offsets
    for offset in range(1000):
        codeflash_output = _byte_to_line_index(offset, line_byte_starts); result = codeflash_output # 348μs -> 250μs (39.4% faster)

def test_large_scale_sequential_byte_offsets():
    """Test sequential byte offsets to verify monotonic behavior."""
    # Create 10 lines
    line_byte_starts = [i * 50 for i in range(10)]
    
    # Collect results for sequential offsets
    results = []
    for offset in range(500):
        codeflash_output = _byte_to_line_index(offset, line_byte_starts); result = codeflash_output # 163μs -> 114μs (43.1% faster)
        results.append(result)
    
    # Results should be non-decreasing (monotonic)
    for i in range(1, len(results)):
        pass

def test_large_scale_random_large_offsets():
    """Test with 1000 large random byte offsets."""
    # Create 100 lines with large byte offsets
    line_byte_starts = [i * 100000 for i in range(100)]
    
    # Test various large offsets
    test_offsets = [0, 500000, 1000000, 5000000, 9999999]
    for offset in test_offsets:
        codeflash_output = _byte_to_line_index(offset, line_byte_starts); result = codeflash_output # 3.35μs -> 2.30μs (45.3% faster)

def test_large_scale_stress_empty_lines():
    """Stress test with many consecutive zero-length line starts."""
    # Simulate a file with many empty lines (consecutive same byte values)
    line_byte_starts = [0] * 500 + [500] * 500
    
    # Test offset before the change
    codeflash_output = _byte_to_line_index(250, line_byte_starts); result_before = codeflash_output # 1.19μs -> 832ns (43.3% faster)
    
    # Test offset at the change
    codeflash_output = _byte_to_line_index(500, line_byte_starts); result_at = codeflash_output # 661ns -> 461ns (43.4% faster)
    
    # Test offset after the change
    codeflash_output = _byte_to_line_index(750, line_byte_starts); result_after = codeflash_output # 481ns -> 360ns (33.6% faster)

def test_large_scale_extreme_byte_offsets():
    """Test with extreme byte offset values."""
    # Create a document with just one line
    line_byte_starts = [0]
    
    # Test with very large offsets
    extreme_offsets = [1000000000, 2**31 - 1, 10**18]
    for offset in extreme_offsets:
        codeflash_output = _byte_to_line_index(offset, line_byte_starts); result = codeflash_output # 1.84μs -> 1.20μs (53.3% faster)

def test_large_scale_binary_search_coverage():
    """Test that all line indices are reachable with appropriate offsets."""
    # Create 100 lines
    line_byte_starts = list(range(0, 1000, 10))  # [0, 10, 20, ..., 990]
    
    # For each line, find an offset that maps to it
    for line_idx in range(len(line_byte_starts)):
        # Use the line start plus a small offset
        offset = line_byte_starts[line_idx] + 5
        codeflash_output = _byte_to_line_index(offset, line_byte_starts); result = codeflash_output # 38.0μs -> 27.9μs (36.4% faster)

def test_large_scale_consistency_across_repeated_calls():
    """Test that the function returns consistent results across repeated calls."""
    # Create a document
    line_byte_starts = [i * 50 for i in range(1000)]
    test_offset = 12345
    
    # Call the function 100 times
    results = [_byte_to_line_index(test_offset, line_byte_starts) for _ in range(100)]
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

To edit these changes git checkout codeflash/optimize-pr1580-2026-02-20T06.34.48 and push.

Codeflash

The main optimization here is eliminating the `max(0, idx)` call by handling the edge case directly. Since `bisect_right` returns 0 when `byte_offset` is less than all elements, subtracting 1 gives -1, which we can catch with a simple comparison. This avoids the function call overhead of `max()`.
"""Map a byte offset in body_text to a body_lines index."""
idx = bisect.bisect_right(line_byte_starts, byte_offset) - 1
return max(0, idx)
return max(idx, 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

Note: The optimization in this PR (0 if idx < 0 else idx instead of max(0, idx)) was reverted by prek's FURB136 lint rule back to max(idx, 0). This effectively nullifies the performance improvement this PR intended to provide, since max(idx, 0) is functionally equivalent to the original max(0, idx).

This PR no longer provides any meaningful optimization after the lint auto-fix.

@claude
Copy link
Contributor

claude bot commented Feb 20, 2026

PR Review Summary

Prek Checks

  • 1 auto-fix applied and pushed: FURB136 (if-expr-min-max) in codeflash/languages/java/instrumentation.py — converted 0 if idx < 0 else idx back to max(idx, 0)
  • 12 remaining unfixable issues: 11x G004 (logging f-string) and 1x SIM105 (try-except-pass → contextlib.suppress) — all in parent PR code, not auto-fixable by prek

Mypy

  • 3 errors in instrumentation.py — all pre-existing in parent PR code (no-redef, var-annotated, assignment), not related to the optimization change

Code Review

Critical finding: Optimization nullified by lint rule

The optimization in this PR changed max(0, idx)0 if idx < 0 else idx to avoid function call overhead of max(). However, prek's FURB136 lint rule automatically converted it back to max(idx, 0), which is functionally equivalent to the original code. After the lint auto-fix, this PR provides no meaningful performance improvement.

No bugs, security issues, or breaking API changes found — the change is functionally equivalent to the original.

Test Coverage

File Stmts Miss Coverage Changed Line Covered
codeflash/languages/java/instrumentation.py 507 92 82% ✅ Yes (line 297)
  • The single changed line is covered by existing tests
  • 7 test failures observed are environment-related (Maven dependency resolution issues in CI), not caused by the optimization change
  • No coverage regression — the change is a single-line expression swap

Last updated: 2026-02-20

@claude claude bot merged commit 1f6001f into fix/java-direct-jvm-and-bugs Feb 20, 2026
27 of 34 checks passed
@claude claude bot deleted the codeflash/optimize-pr1580-2026-02-20T06.34.48 branch February 20, 2026 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚡️ codeflash Optimization PR opened by Codeflash AI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants