Skip to content

Conversation

@codeflash-ai
Copy link

@codeflash-ai codeflash-ai bot commented Nov 1, 2025

📄 13% (0.13x) speedup for is_witness in electrum/plugins/ledger/ledger.py

⏱️ Runtime : 589 microseconds 521 microseconds (best of 246 runs)

📝 Explanation and details

The optimized version achieves a 13% speedup by eliminating redundant operations through strategic variable caching:

Key optimizations:

  1. Caches len(script) once - The original code calls len(script) three times (lines with 27.4% and 21.1% of execution time). The optimized version stores it in script_len and reuses it, avoiding repeated length calculations.

  2. Caches script[0] access - Instead of accessing script[0] multiple times in conditional checks and the return statement, it's stored in the first variable and reused.

Why this improves performance:

  • len() calls on bytes objects require traversing the object header to read the length field each time
  • Array indexing script[0] involves bounds checking and memory access that can be avoided through caching
  • Local variable access is faster than attribute/method calls in Python's bytecode execution

Test case performance patterns:

  • Best gains (10-18% faster): Valid witness scripts that pass all checks and reach the final return statement, where both optimizations provide maximum benefit
  • Slight slowdowns (2-16% slower): Very short invalid scripts that exit early in the first condition, where the overhead of variable assignment isn't recovered by reuse
  • Consistent improvements: Longer execution paths and bulk operations show reliable 8-17% speedups

The optimization is most effective for the common case of processing valid or nearly-valid witness scripts where multiple checks are performed.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 2000 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 5 Passed
📊 Tests Coverage 100.0%
🌀 Generated Regression Tests and Runtime
import pytest
from electrum.plugins.ledger.ledger import is_witness

# unit tests

# -------------------------
# Basic Test Cases
# -------------------------

def test_p2wpkh_valid():
    # Valid P2WPKH: OP_0 <20-byte-keyhash>
    script = b'\x00\x14' + b'\x01' * 20
    codeflash_output = is_witness(script); result = codeflash_output # 935ns -> 886ns (5.53% faster)

def test_p2wsh_valid():
    # Valid P2WSH: OP_0 <32-byte-script-hash>
    script = b'\x00\x20' + b'\x02' * 32
    codeflash_output = is_witness(script); result = codeflash_output # 838ns -> 751ns (11.6% faster)

def test_p2wsh_nonzero_version():
    # Valid witness version 1 (OP_1) <32-byte-script-hash>
    script = b'\x51\x20' + b'\x03' * 32
    codeflash_output = is_witness(script); result = codeflash_output # 1.02μs -> 894ns (14.4% faster)

def test_p2wpkh_nonzero_version():
    # Valid witness version 2 (OP_2) <20-byte-keyhash>
    script = b'\x52\x14' + b'\x04' * 20
    codeflash_output = is_witness(script); result = codeflash_output # 1.03μs -> 910ns (13.2% faster)

def test_not_witness_wrong_length():
    # Length less than 4 bytes
    script = b'\x00\x14\x01'
    codeflash_output = is_witness(script); result = codeflash_output # 386ns -> 433ns (10.9% slower)

def test_not_witness_wrong_opcode():
    # First byte not OP_0 or OP_1-OP_16
    script = b'\x50\x14' + b'\x01' * 20
    codeflash_output = is_witness(script); result = codeflash_output # 627ns -> 612ns (2.45% faster)

def test_not_witness_wrong_program_length():
    # Second byte does not match program length
    script = b'\x00\x13' + b'\x01' * 20  # 0x13 = 19, but 20 bytes follow
    codeflash_output = is_witness(script); result = codeflash_output # 677ns -> 653ns (3.68% faster)

# -------------------------
# Edge Test Cases
# -------------------------

def test_minimum_length():
    # Minimum valid length: 4 bytes
    script = b'\x00\x02\x01\x02'
    codeflash_output = is_witness(script); result = codeflash_output # 944ns -> 879ns (7.39% faster)

def test_maximum_length():
    # Maximum valid length: 42 bytes
    script = b'\x00\x28' + b'\x05' * 40
    codeflash_output = is_witness(script); result = codeflash_output # 928ns -> 851ns (9.05% faster)

def test_length_too_short():
    # Too short (<4 bytes)
    script = b'\x00\x01\x02'
    codeflash_output = is_witness(script); result = codeflash_output # 389ns -> 414ns (6.04% slower)

def test_length_too_long():
    # Too long (>42 bytes)
    script = b'\x00\x29' + b'\x06' * 41
    codeflash_output = is_witness(script); result = codeflash_output # 479ns -> 486ns (1.44% slower)

def test_opcode_edge_low():
    # OP_1 (0x51), valid witness version 1
    script = b'\x51\x14' + b'\x07' * 20
    codeflash_output = is_witness(script); result = codeflash_output # 1.19μs -> 1.03μs (15.0% faster)

def test_opcode_edge_high():
    # OP_16 (0x60), valid witness version 16
    script = b'\x60\x14' + b'\x08' * 20
    codeflash_output = is_witness(script); result = codeflash_output # 1.11μs -> 942ns (18.2% faster)

def test_opcode_above_range():
    # OP_17 (0x61), invalid witness version
    script = b'\x61\x14' + b'\x09' * 20
    codeflash_output = is_witness(script); result = codeflash_output # 658ns -> 620ns (6.13% faster)

def test_opcode_below_range():
    # OP_0 (0x00) is valid, OP_0x50 (0x50) is not
    script = b'\x50\x14' + b'\x0a' * 20
    codeflash_output = is_witness(script); result = codeflash_output # 577ns -> 596ns (3.19% slower)

def test_program_length_zero():
    # Program length is zero, which means script is 2 bytes (invalid, too short)
    script = b'\x00\x00'
    codeflash_output = is_witness(script); result = codeflash_output # 371ns -> 386ns (3.89% slower)

def test_program_length_one():
    # Program length is one, script is 3 bytes (invalid, too short)
    script = b'\x00\x01\x01'
    codeflash_output = is_witness(script); result = codeflash_output # 354ns -> 382ns (7.33% slower)

def test_program_length_mismatch():
    # Second byte does not match actual program length
    script = b'\x00\x14' + b'\x0b' * 19  # 19 bytes instead of 20
    codeflash_output = is_witness(script); result = codeflash_output # 705ns -> 666ns (5.86% faster)


def test_empty_script():
    # Empty script should return False
    script = b''
    codeflash_output = is_witness(script); result = codeflash_output # 524ns -> 591ns (11.3% slower)

def test_invalid_type_str():
    # Passing a string instead of bytes should raise TypeError
    with pytest.raises(TypeError):
        is_witness('\x00\x14' + '\x01'*20) # 1.81μs -> 1.76μs (2.73% faster)

# -------------------------
# Large Scale Test Cases
# -------------------------

def test_large_valid_script():
    # Test with maximum allowed program length (40 bytes)
    script = b'\x00\x28' + b'\xff' * 40
    codeflash_output = is_witness(script); result = codeflash_output # 1.09μs -> 1.06μs (2.55% faster)

def test_large_invalid_script():
    # Test with program just above the allowed length (41 bytes)
    script = b'\x00\x29' + b'\xff' * 41
    codeflash_output = is_witness(script); result = codeflash_output # 501ns -> 504ns (0.595% slower)

def test_all_valid_versions():
    # Test all witness versions from 0 (OP_0) to 16 (OP_16)
    for version in range(0, 17):
        op_code = 0 if version == 0 else 0x50 + version
        script = bytes([op_code, 20]) + b'\xaa' * 20
        codeflash_output = is_witness(script); result = codeflash_output # 6.58μs -> 5.59μs (17.8% faster)

def test_all_invalid_versions():
    # Test opcodes just outside valid witness range
    for op_code in [80, 97]:  # 0x50, 0x61
        script = bytes([op_code, 20]) + b'\xbb' * 20
        codeflash_output = is_witness(script); result = codeflash_output # 1.05μs -> 977ns (7.57% faster)

def test_bulk_valid_scripts():
    # Test a batch of valid scripts with varying program lengths
    for prog_len in range(2, 41, 5):  # keep under 1000 iterations
        script = b'\x00' + bytes([prog_len]) + b'\x01' * prog_len
        codeflash_output = is_witness(script); result = codeflash_output # 3.10μs -> 2.87μs (8.02% faster)

def test_bulk_invalid_scripts():
    # Test a batch of invalid scripts (wrong program length)
    for prog_len in range(2, 41, 5):
        script = b'\x00' + bytes([prog_len]) + b'\x01' * (prog_len - 1)
        codeflash_output = is_witness(script); result = codeflash_output # 2.28μs -> 2.22μs (2.93% faster)


def test_performance_many_scripts():
    # Test performance with 1000 scripts (all valid)
    for i in range(1000):
        prog_len = 20
        script = b'\x00' + bytes([prog_len]) + bytes([i % 256]) * prog_len
        codeflash_output = is_witness(script); result = codeflash_output # 262μs -> 237μs (10.7% faster)
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
#------------------------------------------------
import pytest
from electrum.plugins.ledger.ledger import is_witness

# unit tests

# 1. Basic Test Cases

def test_p2wpkh_correct():  # Pay-to-Witness-Pubkey-Hash (P2WPKH), version 0, 20-byte program
    script = bytes([0x00, 0x14]) + b'\x11' * 20
    codeflash_output = is_witness(script) # 1.01μs -> 918ns (10.1% faster)

def test_p2wsh_correct():  # Pay-to-Witness-Script-Hash (P2WSH), version 0, 32-byte program
    script = bytes([0x00, 0x20]) + b'\x22' * 32
    codeflash_output = is_witness(script) # 960ns -> 932ns (3.00% faster)

def test_p2wsh_version1():  # Taproot, version 1, 32-byte program
    script = bytes([0x51, 0x20]) + b'\xaa' * 32
    codeflash_output = is_witness(script) # 1.16μs -> 1.04μs (11.2% faster)

def test_p2wsh_version16():  # Highest valid witness version (16), 32-byte program
    script = bytes([0x60, 0x20]) + b'\xbb' * 32
    codeflash_output = is_witness(script) # 1.11μs -> 987ns (12.2% faster)

def test_p2wsh_version2():  # Arbitrary valid witness version 2
    script = bytes([0x52, 0x20]) + b'\xcc' * 32
    codeflash_output = is_witness(script) # 1.08μs -> 969ns (11.7% faster)

# 2. Edge Test Cases

def test_too_short_script():  # Script less than 4 bytes
    script = b'\x00\x14\x01'
    codeflash_output = is_witness(script) # 404ns -> 415ns (2.65% slower)

def test_too_long_script():  # Script longer than 42 bytes
    script = bytes([0x00, 0x28]) + b'\x33' * 40  # 2 + 40 = 42, valid
    codeflash_output = is_witness(script) # 895ns -> 866ns (3.35% faster)
    script = bytes([0x00, 0x29]) + b'\x33' * 41  # 2 + 41 = 43, invalid
    codeflash_output = is_witness(script) # 343ns -> 346ns (0.867% slower)

def test_invalid_version_byte():  # script[0] not 0 or 81-96
    script = bytes([0x01, 0x14]) + b'\x44' * 20
    codeflash_output = is_witness(script) # 641ns -> 586ns (9.39% faster)

def test_invalid_push_opcode():  # script[1] + 2 != len(script)
    script = bytes([0x00, 0x14]) + b'\x55' * 19  # Should be 20 bytes, only 19 provided
    codeflash_output = is_witness(script) # 663ns -> 624ns (6.25% faster)

def test_push_opcode_boundary():  # script[1] = 0, so len(script) == 2
    script = bytes([0x00, 0x00])
    codeflash_output = is_witness(script) # 369ns -> 441ns (16.3% slower)

def test_version_byte_81():  # script[0] == 81 (valid), 1-byte program
    script = bytes([0x51, 0x01, 0x99])
    codeflash_output = is_witness(script) # 382ns -> 393ns (2.80% slower)

def test_version_byte_96():  # script[0] == 96 (valid), 1-byte program
    script = bytes([0x60, 0x01, 0x77])
    codeflash_output = is_witness(script) # 385ns -> 400ns (3.75% slower)

def test_invalid_version_byte_high():  # script[0] == 0x61 (97), invalid
    script = bytes([0x61, 0x01, 0x88])
    codeflash_output = is_witness(script) # 363ns -> 381ns (4.72% slower)

def test_invalid_version_byte_low():  # script[0] == 0x50 (80), invalid
    script = bytes([0x50, 0x01, 0x99])
    codeflash_output = is_witness(script) # 366ns -> 387ns (5.43% slower)


def test_empty_script():  # Empty input
    script = b''
    codeflash_output = is_witness(script) # 430ns -> 427ns (0.703% faster)

def test_push_opcode_max():  # script[1] == 40, len(script) == 42
    script = bytes([0x00, 0x28]) + b'\x66' * 40
    codeflash_output = is_witness(script) # 1.05μs -> 936ns (11.9% faster)

def test_push_opcode_min():  # script[1] == 0x01, len(script) == 3
    script = bytes([0x00, 0x01, 0x01])
    codeflash_output = is_witness(script) # 386ns -> 409ns (5.62% slower)

def test_push_opcode_edge():  # script[1] == 0x02, len(script) == 4
    script = bytes([0x00, 0x02, 0x01, 0x02])
    codeflash_output = is_witness(script) # 993ns -> 889ns (11.7% faster)

# 3. Large Scale Test Cases

def test_large_valid_program():  # 40-byte program, valid
    program = b'\x99' * 40
    script = bytes([0x00, 0x28]) + program
    codeflash_output = is_witness(script) # 981ns -> 847ns (15.8% faster)

def test_large_invalid_program():  # 41-byte program, invalid (len > 42)
    program = b'\x99' * 41
    script = bytes([0x00, 0x29]) + program
    codeflash_output = is_witness(script) # 504ns -> 496ns (1.61% faster)

def test_all_valid_versions():  # Test all valid witness versions (0-16)
    for v in range(0, 17):
        opcode = 0x50 + v if v != 0 else 0x00
        script = bytes([opcode, 0x20]) + b'\x77' * 32
        expected_version = v
        codeflash_output = is_witness(script) # 6.55μs -> 5.60μs (17.0% faster)

def test_all_invalid_versions():  # Test all opcodes just outside valid range
    for opcode in [0x4f, 0x61]:  # 79 and 97
        script = bytes([opcode, 0x20]) + b'\x77' * 32
        codeflash_output = is_witness(script) # 1.06μs -> 968ns (9.61% faster)

def test_many_random_valid_scripts():  # 100 random valid scripts (version 0, 20-byte)
    for i in range(100):
        program = bytes([i % 256] * 20)
        script = bytes([0x00, 0x14]) + program
        codeflash_output = is_witness(script) # 26.7μs -> 24.4μs (9.54% faster)

def test_many_random_invalid_scripts():  # 100 random invalid scripts (wrong push opcode)
    for i in range(100):
        program = bytes([i % 256] * 20)
        script = bytes([0x00, 0x13]) + program  # push opcode says 19, but 20 provided
        codeflash_output = is_witness(script) # 21.6μs -> 20.1μs (7.59% faster)

def test_scalability_varied_lengths():  # Test all valid program lengths (2-40)
    for l in range(2, 41):  # witness programs from 2 to 40 bytes
        script = bytes([0x00, l]) + b'\x55' * l
        codeflash_output = is_witness(script) # 10.9μs -> 10.0μs (8.86% faster)

def test_scalability_all_versions_and_lengths():  # All versions, all valid lengths up to 40
    for v in range(0, 17):
        opcode = 0x50 + v if v != 0 else 0x00
        for l in range(2, 41):
            script = bytes([opcode, l]) + b'\x77' * l
            expected_version = v
            codeflash_output = is_witness(script)
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
#------------------------------------------------
from electrum.plugins.ledger.ledger import is_witness

def test_is_witness():
    is_witness(b'Q\x02\x00\x00')

def test_is_witness_2():
    is_witness(b'')

def test_is_witness_3():
    is_witness(b'Q\x03\x00\x00')

def test_is_witness_4():
    is_witness(b'a\x00\x00\x00')

def test_is_witness_5():
    is_witness(b'\x00\x02\x00\x00')
🔎 Concolic Coverage Tests and Runtime
Test File::Test Function Original ⏱️ Optimized ⏱️ Speedup
codeflash_concolic_nuhjwnyo/tmphswaisuy/test_concolic_coverage.py::test_is_witness 1.40μs 1.25μs 12.0%✅
codeflash_concolic_nuhjwnyo/tmphswaisuy/test_concolic_coverage.py::test_is_witness_2 397ns 429ns -7.46%⚠️
codeflash_concolic_nuhjwnyo/tmphswaisuy/test_concolic_coverage.py::test_is_witness_3 818ns 747ns 9.50%✅
codeflash_concolic_nuhjwnyo/tmphswaisuy/test_concolic_coverage.py::test_is_witness_4 727ns 685ns 6.13%✅
codeflash_concolic_nuhjwnyo/tmphswaisuy/test_concolic_coverage.py::test_is_witness_5 995ns 901ns 10.4%✅

To edit these changes git checkout codeflash/optimize-is_witness-mhfwx78t and push.

Codeflash Static Badge

The optimized version achieves a **13% speedup** by eliminating redundant operations through strategic variable caching:

**Key optimizations:**
1. **Caches `len(script)` once** - The original code calls `len(script)` three times (lines with 27.4% and 21.1% of execution time). The optimized version stores it in `script_len` and reuses it, avoiding repeated length calculations.

2. **Caches `script[0]` access** - Instead of accessing `script[0]` multiple times in conditional checks and the return statement, it's stored in the `first` variable and reused.

**Why this improves performance:**
- `len()` calls on bytes objects require traversing the object header to read the length field each time
- Array indexing `script[0]` involves bounds checking and memory access that can be avoided through caching
- Local variable access is faster than attribute/method calls in Python's bytecode execution

**Test case performance patterns:**
- **Best gains (10-18% faster)**: Valid witness scripts that pass all checks and reach the final return statement, where both optimizations provide maximum benefit
- **Slight slowdowns (2-16% slower)**: Very short invalid scripts that exit early in the first condition, where the overhead of variable assignment isn't recovered by reuse
- **Consistent improvements**: Longer execution paths and bulk operations show reliable 8-17% speedups

The optimization is most effective for the common case of processing valid or nearly-valid witness scripts where multiple checks are performed.
@codeflash-ai codeflash-ai bot requested a review from mashraf-222 November 1, 2025 06:40
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash labels Nov 1, 2025
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 🎯 Quality: High Optimization Quality according to Codeflash

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant