Skip to content

Conversation

@codeflash-ai
Copy link

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

📄 513% (5.13x) speedup for Figure.for_each_mapbox in plotly/graph_objs/_figure.py

⏱️ Runtime : 707 microseconds 115 microseconds (best of 5 runs)

📝 Explanation and details

The optimization adds a fast path for the most common case in select_mapboxes() when no filtering criteria are specified (selector=None, row=None, col=None).

Key Changes:

  • Early detection: Added a condition to check if all filtering parameters are None
  • Direct layout access: Instead of calling the generic _select_layout_subplots_by_prefix() method, it directly accesses self.layout and filters mapbox keys with a list comprehension
  • Generator optimization: Returns a generator expression (layout[k] for k in mapbox_keys) instead of going through the complex generic selection machinery

Why it's faster:
The original code always calls _select_layout_subplots_by_prefix(), which involves generic parameter validation, complex filtering logic, and multiple function calls. The optimized version bypasses this entirely for the common "select all" case, using simple string prefix matching and direct dictionary access instead.

Performance impact:

  • select_mapboxes() time reduced from 2.19ms to 0.64ms (71% faster)
  • Overall for_each_mapbox() runtime improved from 707μs to 115μs (512% speedup)

Test case benefits:
This optimization is particularly effective for test cases with no filtering criteria, as shown in the annotated tests where all cases achieved 500%+ speedup. The optimization maintains identical behavior while dramatically improving performance for the most common usage pattern of selecting all mapbox objects without any filters.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 8 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Generated Regression Tests and Runtime
import pytest
from plotly.graph_objs._figure import Figure


# Minimal stub classes to simulate Plotly Figure and Mapbox objects
class Mapbox:
    def __init__(self, **props):
        self.__dict__.update(props)

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

# 1. Basic Test Cases






def test_for_each_mapbox_with_no_mapboxes():
    fig = Figure(layout={})
    called = []
    fig.for_each_mapbox(lambda mb: called.append(True)) # 179μs -> 29.9μs (500% faster)

# 2. Edge Test Cases

def test_for_each_mapbox_with_none_layout():
    fig = Figure(layout=None)
    called = []
    fig.for_each_mapbox(lambda mb: called.append(True)) # 168μs -> 27.6μs (513% faster)





def test_for_each_mapbox_with_mapbox_none():
    fig = Figure(layout={"mapbox": None})
    called = []
    fig.for_each_mapbox(lambda mb: called.append(True)) # 179μs -> 28.2μs (534% faster)








#------------------------------------------------
import pytest
from plotly.graph_objs._figure import Figure


# Minimal stub classes to simulate Plotly's Figure and Mapbox objects
class Mapbox:
    def __init__(self, **kwargs):
        self._props = kwargs
        for k, v in kwargs.items():
            setattr(self, k, v)

    def __getitem__(self, k):
        return self._props[k]

    def __setitem__(self, k, v):
        self._props[k] = v
        setattr(self, k, v)

    def __contains__(self, k):
        return k in self._props

    def __repr__(self):
        return f"Mapbox({self._props})"

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

# ----------- BASIC TEST CASES -----------






def test_edge_no_mapboxes():
    # No mapbox objects: function should not be called, no error
    fig = Figure({})
    called = []
    fig.for_each_mapbox(lambda mb: called.append(True)) # 179μs -> 29.7μs (506% faster)

To edit these changes git checkout codeflash/optimize-Figure.for_each_mapbox-mhg1gsyw and push.

Codeflash Static Badge

The optimization adds a fast path for the most common case in `select_mapboxes()` when no filtering criteria are specified (selector=None, row=None, col=None). 

**Key Changes:**
- **Early detection**: Added a condition to check if all filtering parameters are None
- **Direct layout access**: Instead of calling the generic `_select_layout_subplots_by_prefix()` method, it directly accesses `self.layout` and filters mapbox keys with a list comprehension
- **Generator optimization**: Returns a generator expression `(layout[k] for k in mapbox_keys)` instead of going through the complex generic selection machinery

**Why it's faster:**
The original code always calls `_select_layout_subplots_by_prefix()`, which involves generic parameter validation, complex filtering logic, and multiple function calls. The optimized version bypasses this entirely for the common "select all" case, using simple string prefix matching and direct dictionary access instead.

**Performance impact:**
- `select_mapboxes()` time reduced from 2.19ms to 0.64ms (71% faster)
- Overall `for_each_mapbox()` runtime improved from 707μs to 115μs (512% speedup)

**Test case benefits:**
This optimization is particularly effective for test cases with no filtering criteria, as shown in the annotated tests where all cases achieved 500%+ speedup. The optimization maintains identical behavior while dramatically improving performance for the most common usage pattern of selecting all mapbox objects without any filters.
@codeflash-ai codeflash-ai bot requested a review from mashraf-222 November 1, 2025 08:47
@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