Skip to content

Conversation

@codeflash-ai
Copy link

@codeflash-ai codeflash-ai bot commented Dec 4, 2025

📄 176% (1.76x) speedup for are_events_compatible in inference/core/interfaces/stream/watchdog.py

⏱️ Runtime : 1.02 milliseconds 371 microseconds (best of 47 runs)

📝 Explanation and details

The optimized code achieves a 175% speedup by eliminating expensive operations and reducing memory allocations through three key optimizations:

1. Early Exit Strategy

  • Original: Always checks any(e is None for e in events) which scans the entire list even when the first element is None
  • Optimized: Uses if not events for empty lists and checks events[0] is None immediately, avoiding unnecessary iteration

2. Single-Pass Validation

  • Original: Creates two intermediate data structures (any() generator + frame_ids list) and performs two complete list traversals
  • Optimized: Uses one for loop that checks both None values and frame_id equality simultaneously, eliminating the need for intermediate collections

3. Reduced Memory Pressure

  • Original: Allocates a frame_ids list containing all frame_id values before comparison
  • Optimized: Stores only first_id and compares directly during iteration, avoiding list allocation entirely

Performance Impact by Test Case:

  • Best gains: Large lists with early mismatches (4837% faster for alternating frame_ids) because the optimized version exits immediately on the first mismatch
  • Consistent gains: All compatible scenarios show 160-220% speedup due to eliminated allocations
  • Edge case: Large lists with None elements show slight regression (-12 to -17%) due to different iteration patterns, but this is rare and the overall gain is substantial

Function Usage Context:
Based on compute_events_latency() calling this function with just 2 events, this optimization is particularly valuable since it's likely called frequently in event processing pipelines where latency calculations are performance-critical.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 11 Passed
🌀 Generated Regression Tests 49 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
⚙️ Existing Unit Tests and Runtime
Test File::Test Function Original ⏱️ Optimized ⏱️ Speedup
inference/unit_tests/core/interfaces/stream/test_watchdog.py::test_are_events_compatible_when_empty_event_given 1.71μs 754ns 126%✅
inference/unit_tests/core/interfaces/stream/test_watchdog.py::test_are_events_compatible_when_events_related_to_different_frames_given 3.32μs 1.19μs 180%✅
inference/unit_tests/core/interfaces/stream/test_watchdog.py::test_are_events_compatible_when_events_related_to_the_same_frame_given 3.35μs 1.24μs 171%✅
inference/unit_tests/core/interfaces/stream/test_watchdog.py::test_are_events_compatible_when_no_events_given 1.51μs 678ns 123%✅
🌀 Generated Regression Tests and Runtime
from typing import List, Optional

# imports
import pytest  # used for our unit tests
from inference.core.interfaces.stream.watchdog import are_events_compatible


# Minimal ModelActivityEvent class for testing
class ModelActivityEvent:
    def __init__(self, frame_id):
        self.frame_id = frame_id


from inference.core.interfaces.stream.watchdog import are_events_compatible

# unit tests

# --- Basic Test Cases ---


def test_single_event_compatible():
    # One event should be compatible with itself
    event = ModelActivityEvent(1)
    codeflash_output = are_events_compatible([event])  # 2.53μs -> 803ns (215% faster)


def test_two_events_same_frame_id():
    # Two events with the same frame_id should be compatible
    event1 = ModelActivityEvent(42)
    event2 = ModelActivityEvent(42)
    codeflash_output = are_events_compatible(
        [event1, event2]
    )  # 2.47μs -> 877ns (182% faster)


def test_multiple_events_same_frame_id():
    # Multiple events with the same frame_id should be compatible
    events = [ModelActivityEvent(7) for _ in range(5)]
    codeflash_output = are_events_compatible(events)  # 2.67μs -> 889ns (200% faster)


def test_two_events_different_frame_id():
    # Two events with different frame_id should not be compatible
    event1 = ModelActivityEvent(1)
    event2 = ModelActivityEvent(2)
    codeflash_output = are_events_compatible(
        [event1, event2]
    )  # 2.67μs -> 888ns (200% faster)


def test_multiple_events_mixed_frame_ids():
    # Multiple events, not all frame_ids match
    events = [ModelActivityEvent(3), ModelActivityEvent(3), ModelActivityEvent(4)]
    codeflash_output = are_events_compatible(events)  # 2.67μs -> 846ns (216% faster)


# --- Edge Test Cases ---


def test_empty_event_list():
    # Empty list should be incompatible
    codeflash_output = are_events_compatible([])  # 1.04μs -> 358ns (192% faster)


def test_list_with_none_event():
    # Any list containing None should be incompatible
    event1 = ModelActivityEvent(1)
    codeflash_output = are_events_compatible(
        [event1, None]
    )  # 1.31μs -> 812ns (60.8% faster)


def test_list_all_none_events():
    # All elements are None
    codeflash_output = are_events_compatible(
        [None, None]
    )  # 1.19μs -> 452ns (162% faster)


def test_list_some_none_events():
    # Some events are valid, some are None
    event1 = ModelActivityEvent(1)
    event2 = ModelActivityEvent(1)
    codeflash_output = are_events_compatible(
        [event1, None, event2]
    )  # 1.26μs -> 801ns (57.3% faster)


def test_list_with_non_integer_frame_id():
    # frame_id is not an integer, but all are equal
    event1 = ModelActivityEvent("abc")
    event2 = ModelActivityEvent("abc")
    codeflash_output = are_events_compatible(
        [event1, event2]
    )  # 2.61μs -> 827ns (216% faster)


def test_list_with_mixed_type_frame_ids():
    # frame_id types differ, should not be compatible
    event1 = ModelActivityEvent(1)
    event2 = ModelActivityEvent("1")
    codeflash_output = are_events_compatible(
        [event1, event2]
    )  # 2.56μs -> 883ns (190% faster)


def test_list_with_negative_frame_ids():
    # Negative frame_id, all equal
    events = [ModelActivityEvent(-5) for _ in range(3)]
    codeflash_output = are_events_compatible(events)  # 2.58μs -> 853ns (203% faster)


def test_list_with_float_frame_ids():
    # All frame_ids are float and equal
    events = [ModelActivityEvent(3.14) for _ in range(2)]
    codeflash_output = are_events_compatible(events)  # 2.42μs -> 851ns (184% faster)


def test_list_with_float_and_int_frame_ids():
    # frame_id types differ (float vs int), should not be compatible
    event1 = ModelActivityEvent(3)
    event2 = ModelActivityEvent(3.0)
    codeflash_output = are_events_compatible(
        [event1, event2]
    )  # 2.47μs -> 903ns (173% faster)


# --- Large Scale Test Cases ---


def test_large_list_all_same_frame_id():
    # Large list, all frame_ids are the same
    events = [ModelActivityEvent(100) for _ in range(1000)]
    codeflash_output = are_events_compatible(events)  # 65.7μs -> 25.0μs (163% faster)


def test_large_list_one_different_frame_id():
    # Large list, one event has a different frame_id
    events = [ModelActivityEvent(200) for _ in range(999)]
    events.append(ModelActivityEvent(201))
    codeflash_output = are_events_compatible(events)  # 67.2μs -> 25.0μs (168% faster)


def test_large_list_with_none_event():
    # Large list, one event is None
    events = [ModelActivityEvent(300) for _ in range(999)]
    events.append(None)
    codeflash_output = are_events_compatible(events)  # 20.5μs -> 24.8μs (17.1% slower)


def test_large_list_all_none():
    # Large list, all events are None
    events = [None for _ in range(1000)]
    codeflash_output = are_events_compatible(events)  # 1.30μs -> 465ns (180% faster)


def test_large_list_alternating_frame_ids():
    # Large list, alternating frame_ids
    events = [ModelActivityEvent(i % 2) for i in range(1000)]
    codeflash_output = are_events_compatible(events)  # 39.6μs -> 803ns (4837% faster)


def test_large_list_all_same_non_integer_frame_id():
    # Large list, all frame_ids are the same string
    events = [ModelActivityEvent("frameX") for _ in range(1000)]
    codeflash_output = are_events_compatible(events)  # 66.9μs -> 25.4μs (163% faster)


def test_large_list_first_frame_id_different():
    # Large list, first event has a different frame_id
    events = [ModelActivityEvent(400) for _ in range(999)]
    events.insert(0, ModelActivityEvent(401))
    codeflash_output = are_events_compatible(events)  # 39.0μs -> 887ns (4298% faster)


def test_large_list_last_frame_id_different():
    # Large list, last event has a different frame_id
    events = [ModelActivityEvent(500) for _ in range(999)]
    events.append(ModelActivityEvent(501))
    codeflash_output = are_events_compatible(events)  # 65.4μs -> 25.1μs (160% faster)


# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
from typing import List, Optional

# imports
import pytest
from inference.core.interfaces.stream.watchdog import are_events_compatible


# Mock ModelActivityEvent for testing
class ModelActivityEvent:
    def __init__(self, frame_id):
        self.frame_id = frame_id


from inference.core.interfaces.stream.watchdog import are_events_compatible

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


def test_all_events_same_frame_id():
    # All events have the same frame_id, should return True
    events = [ModelActivityEvent(1), ModelActivityEvent(1), ModelActivityEvent(1)]
    codeflash_output = are_events_compatible(events)  # 2.74μs -> 914ns (200% faster)


def test_events_with_different_frame_ids():
    # Events have different frame_ids, should return False
    events = [ModelActivityEvent(1), ModelActivityEvent(2), ModelActivityEvent(1)]
    codeflash_output = are_events_compatible(events)  # 2.90μs -> 922ns (215% faster)


def test_single_event():
    # Only one event, should return True
    events = [ModelActivityEvent(42)]
    codeflash_output = are_events_compatible(events)  # 2.29μs -> 736ns (211% faster)


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


def test_empty_events_list():
    # Empty list should return False
    events = []
    codeflash_output = are_events_compatible(events)  # 1.14μs -> 394ns (190% faster)


def test_events_with_none():
    # List contains None, should return False
    events = [ModelActivityEvent(1), None, ModelActivityEvent(1)]
    codeflash_output = are_events_compatible(events)  # 1.46μs -> 819ns (78.6% faster)


def test_all_none_events():
    # All events are None, should return False
    events = [None, None, None]
    codeflash_output = are_events_compatible(events)  # 1.24μs -> 417ns (198% faster)


def test_event_with_frame_id_zero():
    # All events have frame_id 0, should return True
    events = [ModelActivityEvent(0), ModelActivityEvent(0)]
    codeflash_output = are_events_compatible(events)  # 2.51μs -> 851ns (195% faster)


def test_event_with_negative_frame_id():
    # All events have the same negative frame_id, should return True
    events = [ModelActivityEvent(-5), ModelActivityEvent(-5)]
    codeflash_output = are_events_compatible(events)  # 2.39μs -> 830ns (188% faster)


def test_event_with_mixed_negative_and_positive_frame_ids():
    # Events have mixed negative and positive frame_ids, should return False
    events = [ModelActivityEvent(-1), ModelActivityEvent(1)]
    codeflash_output = are_events_compatible(events)  # 2.54μs -> 828ns (207% faster)


def test_event_with_large_integers():
    # All events have the same large frame_id, should return True
    big = 10**18
    events = [ModelActivityEvent(big), ModelActivityEvent(big)]
    codeflash_output = are_events_compatible(events)  # 2.31μs -> 786ns (195% faster)


def test_event_with_different_types_of_frame_id():
    # Events have frame_ids of different types (int and str), should return False
    events = [ModelActivityEvent(1), ModelActivityEvent("1")]
    codeflash_output = are_events_compatible(events)  # 2.68μs -> 921ns (191% faster)


def test_event_with_all_unique_frame_ids():
    # All events have unique frame_ids, should return False
    events = [ModelActivityEvent(i) for i in range(3)]
    codeflash_output = are_events_compatible(events)  # 2.51μs -> 832ns (202% faster)


def test_event_with_all_same_object_reference():
    # All events are the same object, should return True
    e = ModelActivityEvent(5)
    events = [e, e, e]
    codeflash_output = are_events_compatible(events)  # 2.48μs -> 863ns (188% faster)


def test_event_with_duplicate_but_not_identical_objects():
    # Different objects but same frame_id, should return True
    events = [ModelActivityEvent(7), ModelActivityEvent(7)]
    codeflash_output = are_events_compatible(events)  # 2.35μs -> 800ns (193% faster)


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


def test_large_list_all_same_frame_id():
    # Large list of events with the same frame_id, should return True
    events = [ModelActivityEvent(123)] * 1000
    codeflash_output = are_events_compatible(events)  # 65.5μs -> 23.8μs (176% faster)


def test_large_list_one_different_frame_id():
    # Large list where one event has a different frame_id, should return False
    events = [ModelActivityEvent(123)] * 999 + [ModelActivityEvent(456)]
    codeflash_output = are_events_compatible(events)  # 66.4μs -> 23.6μs (181% faster)


def test_large_list_with_none():
    # Large list with one None in it, should return False
    events = [ModelActivityEvent(321)] * 500 + [None] + [ModelActivityEvent(321)] * 499
    codeflash_output = are_events_compatible(events)  # 10.8μs -> 12.4μs (12.3% slower)


def test_large_list_all_unique_frame_ids():
    # Large list where all frame_ids are unique, should return False
    events = [ModelActivityEvent(i) for i in range(1000)]
    codeflash_output = are_events_compatible(events)  # 39.8μs -> 895ns (4350% faster)


def test_large_list_all_same_negative_frame_id():
    # Large list with the same negative frame_id, should return True
    events = [ModelActivityEvent(-999)] * 1000
    codeflash_output = are_events_compatible(events)  # 64.7μs -> 23.8μs (172% faster)


def test_large_list_all_same_string_frame_id():
    # Large list with string frame_ids, all the same, should return True
    events = [ModelActivityEvent("frame42")] * 1000
    codeflash_output = are_events_compatible(events)  # 65.4μs -> 24.8μs (163% faster)


def test_large_list_with_mixed_types():
    # Large list with mixed types, should return False
    events = [ModelActivityEvent(1)] * 999 + [ModelActivityEvent("1")]
    codeflash_output = are_events_compatible(events)  # 65.9μs -> 24.2μs (173% faster)


# -------------------------
# Mutation Testing Guards
# -------------------------


def test_mutation_guard_none_short_circuit():
    # If None is present, should return False even if frame_ids would match
    events = [None, ModelActivityEvent(1), ModelActivityEvent(1)]
    codeflash_output = are_events_compatible(events)  # 1.26μs -> 464ns (173% faster)


def test_mutation_guard_empty_list():
    # Empty list should always return False
    codeflash_output = are_events_compatible([])  # 1.06μs -> 345ns (206% faster)


def test_mutation_guard_all_same_but_one_none():
    # List of same frame_ids but one None, should return False
    events = [ModelActivityEvent(5)] * 999 + [None]
    codeflash_output = are_events_compatible(events)  # 20.3μs -> 23.8μs (14.9% slower)


def test_mutation_guard_all_same_but_one_different():
    # List of same frame_ids but last is different, should return False
    events = [ModelActivityEvent(7)] * 999 + [ModelActivityEvent(8)]
    codeflash_output = are_events_compatible(events)  # 66.8μs -> 23.7μs (182% faster)


def test_mutation_guard_all_same_type_but_different_value():
    # All ints but one is different, should return False
    events = (
        [ModelActivityEvent(0)] * 500
        + [ModelActivityEvent(1)]
        + [ModelActivityEvent(0)] * 499
    )
    codeflash_output = are_events_compatible(events)  # 52.3μs -> 12.4μs (323% faster)


def test_mutation_guard_all_same_object_reference_large():
    # All references to same object, should return True
    e = ModelActivityEvent(123456)
    events = [e] * 1000
    codeflash_output = are_events_compatible(events)  # 64.4μs -> 23.6μs (173% faster)


# 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-are_events_compatible-miqqaqcg and push.

Codeflash Static Badge

The optimized code achieves a **175% speedup** by eliminating expensive operations and reducing memory allocations through three key optimizations:

**1. Early Exit Strategy**
- **Original**: Always checks `any(e is None for e in events)` which scans the entire list even when the first element is None
- **Optimized**: Uses `if not events` for empty lists and checks `events[0] is None` immediately, avoiding unnecessary iteration

**2. Single-Pass Validation**
- **Original**: Creates two intermediate data structures (`any()` generator + `frame_ids` list) and performs two complete list traversals
- **Optimized**: Uses one `for` loop that checks both None values and frame_id equality simultaneously, eliminating the need for intermediate collections

**3. Reduced Memory Pressure**
- **Original**: Allocates a `frame_ids` list containing all frame_id values before comparison
- **Optimized**: Stores only `first_id` and compares directly during iteration, avoiding list allocation entirely

**Performance Impact by Test Case:**
- **Best gains**: Large lists with early mismatches (4837% faster for alternating frame_ids) because the optimized version exits immediately on the first mismatch
- **Consistent gains**: All compatible scenarios show 160-220% speedup due to eliminated allocations
- **Edge case**: Large lists with None elements show slight regression (-12 to -17%) due to different iteration patterns, but this is rare and the overall gain is substantial

**Function Usage Context:**
Based on `compute_events_latency()` calling this function with just 2 events, this optimization is particularly valuable since it's likely called frequently in event processing pipelines where latency calculations are performance-critical.
@codeflash-ai codeflash-ai bot requested a review from mashraf-222 December 4, 2025 00:59
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash labels Dec 4, 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