Skip to content

Conversation

@codeflash-ai
Copy link

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

📄 10% (0.10x) speedup for _to_table in framework/py/flwr/cli/ls.py

⏱️ Runtime : 2.13 milliseconds 1.94 milliseconds (best of 79 runs)

📝 Explanation and details

The optimized code achieves a 9% speedup through several micro-optimizations that reduce function call overhead and improve string parsing efficiency:

Key Optimizations:

  1. Method Reference Caching: The code caches table.add_column and table.add_row as add_col and append_row respectively. This eliminates repeated attribute lookups during the loop, which is particularly beneficial when processing large run lists (200+ items in the test cases).

  2. Constant Pre-loading: SubStatus.COMPLETED and SubStatus.FAILED are stored in local variables (COMPLETED, FAILED) before the loop. This avoids repeated attribute access on the SubStatus class during status comparisons.

  3. Improved String Parsing: Replaced rsplit(":", maxsplit=1)[-1] with rpartition(":") to extract the sub-status. The rpartition method is more efficient as it returns a 3-tuple directly without creating an intermediate list and indexing operation.

  4. Streamlined Tuple Unpacking: The original code unpacked the row tuple across multiple lines and then created an intermediate formatted_row tuple. The optimized version unpacks directly in one line and passes arguments directly to append_row(), eliminating the intermediate tuple creation.

Performance Impact:
The line profiler shows the most significant improvement in the table.add_row call (69.1% → 78.1% of total time), indicating that while this operation still dominates execution time, the reduced overhead from method caching and eliminating intermediate variables provides measurable gains. These optimizations are especially effective for the large-scale test cases with 200+ runs, where the cumulative effect of reduced function call overhead becomes substantial.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 14 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 1 Passed
📊 Tests Coverage 89.5%
🌀 Generated Regression Tests and Runtime
import pytest  # used for our unit tests
from cli.ls import _to_table


# Mocks for external dependencies
class SubStatus:
    COMPLETED = "COMPLETED"
    FAILED = "FAILED"
    RUNNING = "RUNNING"

# Minimal mock of rich.text.Text for testing
class Text(str):
    def __new__(cls, text, justify=None):
        obj = str.__new__(cls, text)
        obj.justify = justify
        return obj

# Minimal mock of rich.table.Table for testing
class Table:
    def __init__(self, header_style=None, show_lines=None):
        self.header_style = header_style
        self.show_lines = show_lines
        self.columns = []
        self.rows = []

    def add_column(self, text, style=None, no_wrap=False):
        self.columns.append((text, style, no_wrap))

    def add_row(self, *args):
        self.rows.append(args)

    def __repr__(self):
        # For debugging: show columns and rows
        return f"Table(columns={self.columns}, rows={self.rows})"

    # For test assertions: expose row data
    def get_rows(self):
        return self.rows

    def get_columns(self):
        return self.columns
from cli.ls import _to_table

# unit tests

# ---------------------------
# 1. Basic Test Cases
# ---------------------------

def test_empty_run_list():
    """Test with an empty run list."""
    codeflash_output = _to_table([]); table = codeflash_output
















#------------------------------------------------
import pytest
from cli.ls import _to_table
from rich.table import Table
from rich.text import Text

# --- Begin: Mocks for external dependencies ---

# Mocking SubStatus enum, as would be imported from flwr.common.constant
class SubStatus:
    COMPLETED = "COMPLETED"
    FAILED = "FAILED"
    RUNNING = "RUNNING"
    PENDING = "PENDING"
    # Add more if needed
from cli.ls import _to_table

# -------------------------------
# 1. Basic Test Cases
# -------------------------------

def test_empty_run_list():
    """Test that an empty run_list produces a table with only headers and no rows."""
    codeflash_output = _to_table([]); table = codeflash_output
    # Check column headers
    expected_headers = [
        "Run ID", "FAB", "Status", "Elapsed", "Created At", "Running At", "Finished At"
    ]
    actual_headers = [col.header.plain for col in table.columns]




def test_multiple_runs_mixed_status():
    """Test multiple runs with mixed statuses and FAB/version formatting."""
    runs = [
        (
            1, "fabA", "1.0", "irrelevant", f"status:{SubStatus.COMPLETED}",
            "00:01:00", "2024-01-01 10:00", "2024-01-01 10:01", "2024-01-01 10:02"
        ),
        (
            2, "fabB", "2.0", "irrelevant", f"status:{SubStatus.FAILED}",
            "00:02:00", "2024-01-01 11:00", "2024-01-01 11:01", "2024-01-01 11:03"
        ),
        (
            3, "fabC", "3.0", "irrelevant", f"status:{SubStatus.RUNNING}",
            "00:03:00", "2024-01-01 12:00", "2024-01-01 12:01", ""
        ),
    ]
    codeflash_output = _to_table(runs); table = codeflash_output

# -------------------------------
# 2. Edge Test Cases
# -------------------------------


def test_status_not_in_substatus():
    """Test that unknown status values are styled yellow."""
    run = [
        (
            5, "fabE", "5.0", "irrelevant", "status:UNKNOWN",
            "00:00:10", "2024-01-05 16:00", "2024-01-05 16:01", ""
        )
    ]
    codeflash_output = _to_table(run); table = codeflash_output

def test_blank_fields():
    """Test rows with blank or empty string fields."""
    run = [
        (
            6, "", "", "", "status:COMPLETED", "", "", "", ""
        )
    ]
    codeflash_output = _to_table(run); table = codeflash_output

def test_non_integer_run_id():
    """Test that non-integer run_id raises a TypeError (since tuple[int,...] is expected)."""
    run = [
        (
            "not_an_int", "fabF", "6.0", "irrelevant", "status:COMPLETED",
            "00:00:10", "2024-01-06 17:00", "2024-01-06 17:01", ""
        )
    ]
    # The function does not enforce type at runtime, so this will not raise.
    # But we assert that the output still formats correctly.
    codeflash_output = _to_table(run); table = codeflash_output


def test_minimal_and_maximal_length_strings():
    """Test with minimal and maximal reasonable string lengths."""
    min_run = (
        8, "a", "b", "c", "status:COMPLETED", "0", "1", "2", "3"
    )
    max_str = "x" * 100
    max_run = (
        9, max_str, max_str, max_str, f"status:{SubStatus.FAILED}", max_str, max_str, max_str, max_str
    )
    codeflash_output = _to_table([min_run, max_run]); table = codeflash_output

# -------------------------------
# 3. Large Scale Test Cases
# -------------------------------


def test_large_run_list_with_blanks():
    """Test large run_list with some blank fields."""
    N = 200
    runs = []
    for i in range(N):
        fab_id = "" if i % 10 == 0 else f"fab{i}"
        fab_version = "" if i % 15 == 0 else f"{i}.0"
        elapsed = "" if i % 20 == 0 else f"00:{i:02d}:00"
        status = f"status:{SubStatus.COMPLETED}" if i % 2 == 0 else f"status:{SubStatus.FAILED}"
        runs.append((
            i, fab_id, fab_version, "irrelevant", status,
            elapsed, "", "", ""
        ))
    codeflash_output = _to_table(runs); table = codeflash_output
    # Check that blank FAB/versions are formatted as " (v)" or "fabX (v)"
    for i in range(N):
        fab_id = "" if i % 10 == 0 else f"fab{i}"
        fab_version = "" if i % 15 == 0 else f"{i}.0"
        expected_fab = f"{fab_id} (v{fab_version})"
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
#------------------------------------------------
from cli.ls import _to_table

def test__to_table():
    _to_table([(0, '', '', '', '', '', '', '', '')])
🔎 Concolic Coverage Tests and Runtime

To edit these changes git checkout codeflash/optimize-_to_table-mh166eq4 and push.

Codeflash

The optimized code achieves a 9% speedup through several micro-optimizations that reduce function call overhead and improve string parsing efficiency:

**Key Optimizations:**

1. **Method Reference Caching**: The code caches `table.add_column` and `table.add_row` as `add_col` and `append_row` respectively. This eliminates repeated attribute lookups during the loop, which is particularly beneficial when processing large run lists (200+ items in the test cases).

2. **Constant Pre-loading**: `SubStatus.COMPLETED` and `SubStatus.FAILED` are stored in local variables (`COMPLETED`, `FAILED`) before the loop. This avoids repeated attribute access on the `SubStatus` class during status comparisons.

3. **Improved String Parsing**: Replaced `rsplit(":", maxsplit=1)[-1]` with `rpartition(":")` to extract the sub-status. The `rpartition` method is more efficient as it returns a 3-tuple directly without creating an intermediate list and indexing operation.

4. **Streamlined Tuple Unpacking**: The original code unpacked the row tuple across multiple lines and then created an intermediate `formatted_row` tuple. The optimized version unpacks directly in one line and passes arguments directly to `append_row()`, eliminating the intermediate tuple creation.

**Performance Impact:**
The line profiler shows the most significant improvement in the `table.add_row` call (69.1% → 78.1% of total time), indicating that while this operation still dominates execution time, the reduced overhead from method caching and eliminating intermediate variables provides measurable gains. These optimizations are especially effective for the large-scale test cases with 200+ runs, where the cumulative effect of reduced function call overhead becomes substantial.
@codeflash-ai codeflash-ai bot requested a review from mashraf-222 October 21, 2025 23:02
@codeflash-ai codeflash-ai bot added the ⚡️ codeflash Optimization PR opened by Codeflash AI label Oct 21, 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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant