Skip to content

Conversation

@codeflash-ai
Copy link

@codeflash-ai codeflash-ai bot commented Oct 30, 2025

📄 6% (0.06x) speedup for MetricThresholdFilter.__repr__ in wandb/automations/_filters/run_metrics.py

⏱️ Runtime : 494 microseconds 466 microseconds (best of 59 runs)

📝 Explanation and details

The optimization improves performance by caching attribute access and reducing redundant property lookups.

Key changes:

  • Cached attribute access: Instead of accessing self.agg, self.name, self.threshold, and self.cmp multiple times throughout the method, each attribute is accessed once and stored in a local variable
  • Eliminated redundant lookups: The original code accessed self.agg twice (once for the conditional check and once for .value), self.name twice, self.threshold twice, and self.cmp twice

Why this optimization works:

  • In Python, attribute access (self.attribute) involves dictionary lookups and method calls, which have overhead compared to local variable access
  • Local variables are stored in a fast array-like structure and accessed by index, making them significantly faster than attribute lookups
  • The optimization reduces the total number of attribute accesses from 6-7 to 4, cutting attribute lookup overhead by ~40%

Performance characteristics:
The test results show consistent 5-23% speedup across different scenarios, with the best improvements (20-23%) seen in simpler cases with shorter string representations where attribute access overhead represents a larger proportion of total execution time. The optimization is most effective for frequently called __repr__ methods, particularly beneficial when filters are created and represented in bulk operations (as seen in the 1000-filter test case with 5.22% improvement).

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 2048 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Generated Regression Tests and Runtime
from dataclasses import dataclass
# function to test
from typing import Literal, Optional, Union

# imports
import pytest  # used for our unit tests
from wandb.automations._filters.run_metrics import MetricThresholdFilter


# Minimal mock for Agg to support .value attribute
class Agg:
    def __init__(self, value):
        self.value = value

# Minimal mock for PositiveInt, StrictInt, StrictFloat
PositiveInt = int
StrictInt = int
StrictFloat = float

# Minimal mock for BaseMetricFilter
class BaseMetricFilter:
    pass

# The mapping for MongoDB operators
MONGO2PY_OPS = {
    "$eq": "==",
    "$ne": "!=",
    "$gt": ">",
    "$lt": "<",
    "$gte": ">=",
    "$lte": "<=",
}
from wandb.automations._filters.run_metrics import MetricThresholdFilter

# -------------------
# UNIT TESTS
# -------------------

# 1. BASIC TEST CASES

def test_repr_basic_no_agg_int_threshold():
    """Test __repr__ with no aggregation and integer threshold."""
    f = MetricThresholdFilter(name="accuracy", agg=None, cmp="$gte", threshold=0)
    # Should produce: repr("accuracy >= 0")
    codeflash_output = f.__repr__() # 2.31μs -> 1.89μs (22.3% faster)


def test_repr_basic_different_cmp_ops():
    """Test all supported comparison operators."""
    for cmp, py_op in [("$gte", ">="), ("$gt", ">"), ("$lt", "<"), ("$lte", "<=")]:
        f = MetricThresholdFilter(name="score", agg=None, cmp=cmp, threshold=42)
        expected = repr(f"score {py_op} 42")
        codeflash_output = f.__repr__() # 3.88μs -> 3.36μs (15.4% faster)

# 2. EDGE TEST CASES

def test_repr_edge_empty_name():
    """Test __repr__ with empty metric name."""
    f = MetricThresholdFilter(name="", agg=None, cmp="$gte", threshold=1)
    codeflash_output = f.__repr__() # 2.23μs -> 1.88μs (18.6% faster)

def test_repr_edge_special_characters_in_name():
    """Test __repr__ with metric name containing special characters."""
    special_name = "acc@v2#test"
    f = MetricThresholdFilter(name=special_name, agg=None, cmp="$lt", threshold=2)
    codeflash_output = f.__repr__() # 2.29μs -> 1.87μs (22.4% faster)


def test_repr_edge_negative_threshold():
    """Test __repr__ with negative threshold value."""
    f = MetricThresholdFilter(name="loss", agg=None, cmp="$gt", threshold=-0.001)
    codeflash_output = f.__repr__() # 4.52μs -> 4.10μs (10.2% faster)

def test_repr_edge_zero_threshold():
    """Test __repr__ with threshold value of zero."""
    f = MetricThresholdFilter(name="accuracy", agg=None, cmp="$lte", threshold=0)
    codeflash_output = f.__repr__() # 2.26μs -> 1.87μs (20.8% faster)

def test_repr_edge_large_float_threshold():
    """Test __repr__ with very large float threshold."""
    f = MetricThresholdFilter(name="score", agg=None, cmp="$gte", threshold=1e100)
    codeflash_output = f.__repr__() # 6.34μs -> 5.83μs (8.82% faster)



def test_repr_edge_float_threshold_int_repr():
    """Test __repr__ with float threshold that looks like int."""
    f = MetricThresholdFilter(name="score", agg=None, cmp="$lt", threshold=42.0)
    codeflash_output = f.__repr__() # 3.66μs -> 3.38μs (8.31% faster)

# 3. LARGE SCALE TEST CASES




def test_repr_large_scale_high_threshold():
    """Test __repr__ with a very high threshold value."""
    high_threshold = 999_999_999
    f = MetricThresholdFilter(name="score", agg=None, cmp="$gte", threshold=high_threshold)
    codeflash_output = f.__repr__() # 2.32μs -> 1.98μs (17.2% faster)

def test_repr_large_scale_small_threshold():
    """Test __repr__ with a very small threshold value."""
    small_threshold = 1e-12
    f = MetricThresholdFilter(name="score", agg=None, cmp="$lt", threshold=small_threshold)
    codeflash_output = f.__repr__() # 6.28μs -> 5.77μs (8.85% faster)
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
#------------------------------------------------
from dataclasses import dataclass
from typing import Optional, Union

# imports
import pytest  # used for our unit tests
from wandb.automations._filters.run_metrics import MetricThresholdFilter

# --- Begin: minimal stubs for dependencies ---

# Minimal stub for Agg enum-like class
class Agg:
    def __init__(self, value):
        self.value = value

# Minimal stub for BaseMetricFilter
class BaseMetricFilter:
    pass

# --- End: minimal stubs for dependencies ---

# Maps MongoDB comparison operators -> Python literal (str) representations
MONGO2PY_OPS = {
    "$eq": "==",
    "$ne": "!=",
    "$gt": ">",
    "$lt": "<",
    "$gte": ">=",
    "$lte": "<=",
}
from wandb.automations._filters.run_metrics import MetricThresholdFilter

# --- Begin: Unit Tests ---

# 1. Basic Test Cases


def test_repr_basic_without_agg_and_float_threshold():
    # Test without aggregation and float threshold
    filt = MetricThresholdFilter(name="loss", agg=None, cmp="$lt", threshold=0.05)
    # Should be: 'loss < 0.05'
    codeflash_output = filt.__repr__() # 4.29μs -> 4.05μs (6.00% faster)




def test_repr_edge_empty_name():
    # Empty metric name
    filt = MetricThresholdFilter(name="", agg=None, cmp="$gt", threshold=10)
    codeflash_output = filt.__repr__() # 2.22μs -> 1.83μs (21.1% faster)


def test_repr_edge_threshold_zero():
    # Threshold is zero
    filt = MetricThresholdFilter(name="metric", agg=None, cmp="$lte", threshold=0)
    codeflash_output = filt.__repr__() # 2.23μs -> 1.80μs (23.7% faster)

def test_repr_edge_threshold_negative():
    # Threshold is negative
    filt = MetricThresholdFilter(name="metric", agg=None, cmp="$lt", threshold=-1.23)
    codeflash_output = filt.__repr__() # 4.27μs -> 4.06μs (5.15% faster)



def test_repr_edge_float_threshold_high_precision():
    # Very high precision float
    filt = MetricThresholdFilter(name="loss", agg=None, cmp="$lt", threshold=0.1234567890123456)
    # Python repr rounds to 17 digits for float
    codeflash_output = filt.__repr__() # 4.65μs -> 4.41μs (5.35% faster)

def test_repr_edge_metric_name_with_spaces():
    # Metric name with spaces
    filt = MetricThresholdFilter(name="val accuracy", agg=None, cmp="$gte", threshold=0.9)
    codeflash_output = filt.__repr__() # 4.47μs -> 4.25μs (5.32% faster)

def test_repr_edge_metric_name_with_escape_chars():
    # Metric name with escape characters
    filt = MetricThresholdFilter(name="acc\nuracy", agg=None, cmp="$gte", threshold=0.9)
    # The repr should preserve the escape sequence
    codeflash_output = filt.__repr__() # 4.33μs -> 4.24μs (2.12% faster)

def test_repr_edge_threshold_is_large_int():
    # Large integer threshold
    filt = MetricThresholdFilter(name="score", agg=None, cmp="$gt", threshold=999999999)
    codeflash_output = filt.__repr__() # 2.29μs -> 2.00μs (14.4% faster)

def test_repr_edge_threshold_is_large_negative_int():
    # Large negative integer threshold
    filt = MetricThresholdFilter(name="score", agg=None, cmp="$lt", threshold=-999999999)
    codeflash_output = filt.__repr__() # 2.32μs -> 1.91μs (21.3% faster)







def test_repr_large_scale_high_float_threshold():
    # High float threshold
    filt = MetricThresholdFilter(name="score", agg=None, cmp="$gt", threshold=1e308)
    codeflash_output = filt.__repr__() # 6.43μs -> 6.15μs (4.65% faster)


def test_repr_large_scale_many_filters_with_none_agg():
    # 1000 filters with agg=None
    for i in range(1000):
        filt = MetricThresholdFilter(name=f"m{i}", agg=None, cmp="$lt", threshold=i)
        codeflash_output = filt.__repr__() # 417μs -> 396μs (5.22% 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-MetricThresholdFilter.__repr__-mhdkmeei and push.

Codeflash Static Badge

The optimization improves performance by **caching attribute access** and **reducing redundant property lookups**. 

**Key changes:**
- **Cached attribute access**: Instead of accessing `self.agg`, `self.name`, `self.threshold`, and `self.cmp` multiple times throughout the method, each attribute is accessed once and stored in a local variable
- **Eliminated redundant lookups**: The original code accessed `self.agg` twice (once for the conditional check and once for `.value`), `self.name` twice, `self.threshold` twice, and `self.cmp` twice

**Why this optimization works:**
- In Python, attribute access (`self.attribute`) involves dictionary lookups and method calls, which have overhead compared to local variable access
- Local variables are stored in a fast array-like structure and accessed by index, making them significantly faster than attribute lookups
- The optimization reduces the total number of attribute accesses from 6-7 to 4, cutting attribute lookup overhead by ~40%

**Performance characteristics:**
The test results show consistent **5-23% speedup** across different scenarios, with the best improvements (20-23%) seen in simpler cases with shorter string representations where attribute access overhead represents a larger proportion of total execution time. The optimization is most effective for frequently called `__repr__` methods, particularly beneficial when filters are created and represented in bulk operations (as seen in the 1000-filter test case with 5.22% improvement).
@codeflash-ai codeflash-ai bot requested a review from mashraf-222 October 30, 2025 15:20
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: Medium Optimization Quality according to Codeflash labels Oct 30, 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: Medium Optimization Quality according to Codeflash

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant