Skip to content

Conversation

@codeflash-ai
Copy link

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

📄 239% (2.39x) speedup for get_local_contexts in gradio/component_meta.py

⏱️ Runtime : 1.63 milliseconds 482 microseconds (best of 139 runs)

📝 Explanation and details

The optimization eliminates a repeated import cost by moving the from gradio.context import LocalContext statement from inside the function to module scope. This simple change provides a 238% speedup because:

Key Performance Issue: The original code performs a module import and attribute lookup on every function call. The line profiler shows this import taking 49.8% of the total execution time (1.92ms out of 3.86ms total).

Optimization Applied: By caching LocalContext as _LocalContext at module scope, we eliminate the repeated import overhead. The optimized version shows the import cost is completely removed from the function execution path.

Why This Matters: Looking at the function references, get_local_contexts() is called from the updateable decorator wrapper, which is applied to component constructors. This means the function executes every time a Gradio component is created or updated, making it a hot path where even microsecond improvements compound significantly.

Performance Characteristics: The test results show consistent 100-250% speedups across all scenarios:

  • Basic cases: ~200-250% faster
  • Edge cases with different context values: ~200-250% faster
  • Large-scale tests with loops: Up to 249% faster (337μs → 96.6μs)

Impact on Workloads: Since this function is in the component creation/update path, applications that create many components or frequently update them will see the most benefit. The optimization maintains identical behavior while reducing overhead in what appears to be a frequently-called utility function.

The optimization is particularly effective because Python's import mechanism involves dictionary lookups and module loading checks that add significant overhead when repeated thousands of times.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 2123 Passed
⏪ Replay Tests 255 Passed
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Generated Regression Tests and Runtime

from future import annotations

import sys
import types

imports

import pytest
from gradio.component_meta import get_local_contexts

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

def test_defaults_basic():
"""
Test default output when nothing is set.
Should return (False, False).
"""
codeflash_output = get_local_contexts(); result = codeflash_output # 3.19μs -> 995ns (221% faster)

def test_in_event_listener_true():
"""
Test when in_event_listener is set to True.
Should return (True, False).
"""
from gradio.context import LocalContext
LocalContext.in_event_listener.set(True)
# renderable is still unset
codeflash_output = get_local_contexts(); result = codeflash_output # 1.75μs -> 831ns (111% faster)

def test_renderable_true():
"""
Test when renderable is set to a non-None value.
Should return (False, True).
"""
from gradio.context import LocalContext
LocalContext.renderable.set("something")
# in_event_listener is still unset
codeflash_output = get_local_contexts(); result = codeflash_output # 1.83μs -> 745ns (146% faster)

def test_both_true():
"""
Test when both in_event_listener and renderable are set.
Should return (True, True).
"""
from gradio.context import LocalContext
LocalContext.in_event_listener.set(True)
LocalContext.renderable.set(object())
codeflash_output = get_local_contexts(); result = codeflash_output # 1.66μs -> 742ns (123% faster)

def test_both_false_explicit():
"""
Test when both in_event_listener and renderable are explicitly set to False/None.
Should return (False, False).
"""
from gradio.context import LocalContext
LocalContext.in_event_listener.set(False)
LocalContext.renderable.set(None)
codeflash_output = get_local_contexts(); result = codeflash_output # 1.64μs -> 779ns (111% faster)

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

def test_in_event_listener_non_bool():
"""
Test when in_event_listener is set to a non-bool value (e.g., string).
Should return ('yes', False).
"""
from gradio.context import LocalContext
LocalContext.in_event_listener.set("yes")
codeflash_output = get_local_contexts(); result = codeflash_output # 1.65μs -> 796ns (107% faster)

def test_renderable_set_to_false():
"""
Test when renderable is set to False (not None).
Should return (False, True) because False is not None.
"""
from gradio.context import LocalContext
LocalContext.renderable.set(False)
codeflash_output = get_local_contexts(); result = codeflash_output # 1.92μs -> 764ns (151% faster)

def test_in_event_listener_none():
"""
Test when in_event_listener is set to None.
Should return (None, False).
"""
from gradio.context import LocalContext
LocalContext.in_event_listener.set(None)
codeflash_output = get_local_contexts(); result = codeflash_output # 1.64μs -> 818ns (100% faster)

def test_renderable_empty_string():
"""
Test when renderable is set to an empty string.
Should return (False, True).
"""
from gradio.context import LocalContext
LocalContext.renderable.set("")
codeflash_output = get_local_contexts(); result = codeflash_output # 1.82μs -> 731ns (148% faster)

def test_contexts_reset():
"""
Test that after setting and resetting, the function returns defaults.
"""
from gradio.context import LocalContext
LocalContext.in_event_listener.set(True)
LocalContext.renderable.set("abc")
# Now reset
LocalContext.in_event_listener.set(None)
LocalContext.renderable.set(None)
codeflash_output = get_local_contexts(); result = codeflash_output # 1.64μs -> 777ns (111% faster)

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

def test_many_context_changes():
"""
Test the function with many rapid changes to contextvars.
Ensures that the latest value is always returned.
"""
from gradio.context import LocalContext
for i in range(100):
LocalContext.in_event_listener.set(i % 2 == 0)
LocalContext.renderable.set(i)
expected = (i % 2 == 0, True)
codeflash_output = get_local_contexts(); result = codeflash_output # 69.1μs -> 19.9μs (247% faster)
# Reset to default at the end
LocalContext.in_event_listener.set(None)
LocalContext.renderable.set(None)

def test_large_non_none_renderable():
"""
Test with a large object as renderable (e.g., a long string).
Should still return True for renderable.
"""
from gradio.context import LocalContext
long_str = "x" * 999
LocalContext.renderable.set(long_str)
codeflash_output = get_local_contexts(); result = codeflash_output # 1.83μs -> 734ns (149% faster)

def test_large_number_of_set_and_get():
"""
Stress test: set and get contextvars many times to ensure no memory leaks or stale state.
"""
from gradio.context import LocalContext
for i in range(500):
LocalContext.in_event_listener.set(i)
LocalContext.renderable.set(None if i % 2 == 0 else i)
expected = (i, False if i % 2 == 0 else True)
codeflash_output = get_local_contexts(); result = codeflash_output # 337μs -> 96.6μs (249% faster)

def test_large_scale_defaults():
"""
Ensure that after a large number of contextvar changes, resetting to default works.
"""
from gradio.context import LocalContext
for i in range(300):
LocalContext.in_event_listener.set(True)
LocalContext.renderable.set("test")
# Reset
LocalContext.in_event_listener.set(None)
LocalContext.renderable.set(None)
codeflash_output = get_local_contexts(); result = codeflash_output # 1.48μs -> 761ns (94.3% faster)

codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

#------------------------------------------------
from future import annotations

import sys
import types

imports

import pytest
from gradio.component_meta import get_local_contexts

--- Begin test code ---

We'll need to create a mock for gradio.context.LocalContext for testing.

Since we are not allowed to use pytest-mock or similar, we'll monkeypatch sys.modules directly.

class DummyContextVar:
"""
A dummy context variable to simulate the ContextVar API used in LocalContext.
"""
def init(self, default=None):
self.value = default
self.was_set = False

def set(self, value):
    self.value = value
    self.was_set = True

def get(self, default=None):
    if self.was_set:
        return self.value
    return default

class DummyLocalContext:
"""
Dummy LocalContext class with in_event_listener and renderable attributes as context variables.
"""
in_event_listener = DummyContextVar()
renderable = DummyContextVar()

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

def test_default_contexts():
"""
Test default behavior when nothing is set.
Should return (False, False).
"""
# Ensure no value is set
DummyLocalContext.in_event_listener = DummyContextVar()
DummyLocalContext.renderable = DummyContextVar()
codeflash_output = get_local_contexts(); result = codeflash_output # 3.60μs -> 1.01μs (255% faster)

def test_in_event_listener_true_renderable_false():
"""
Test when in_event_listener is set to True, renderable is not set.
Should return (True, False).
"""
DummyLocalContext.in_event_listener = DummyContextVar()
DummyLocalContext.in_event_listener.set(True)
DummyLocalContext.renderable = DummyContextVar()
codeflash_output = get_local_contexts(); result = codeflash_output # 3.31μs -> 986ns (236% faster)

def test_in_event_listener_false_renderable_true():
"""
Test when in_event_listener is False (set), renderable is set to a non-None value.
Should return (False, True).
"""
DummyLocalContext.in_event_listener = DummyContextVar()
DummyLocalContext.in_event_listener.set(False)
DummyLocalContext.renderable = DummyContextVar()
DummyLocalContext.renderable.set("some_value")
codeflash_output = get_local_contexts(); result = codeflash_output # 3.31μs -> 952ns (247% faster)

def test_in_event_listener_true_renderable_true():
"""
Test when both in_event_listener and renderable are set to True/non-None.
Should return (True, True).
"""
DummyLocalContext.in_event_listener = DummyContextVar()
DummyLocalContext.in_event_listener.set(True)
DummyLocalContext.renderable = DummyContextVar()
DummyLocalContext.renderable.set(object())
codeflash_output = get_local_contexts(); result = codeflash_output # 3.27μs -> 1.00μs (227% faster)

------------------- EDGE TEST CASES -------------------

def test_renderable_explicitly_set_to_none():
"""
Test when renderable is explicitly set to None.
The function should return (False, False).
"""
DummyLocalContext.in_event_listener = DummyContextVar()
DummyLocalContext.renderable = DummyContextVar()
DummyLocalContext.renderable.set(None)
codeflash_output = get_local_contexts(); result = codeflash_output # 3.15μs -> 985ns (220% faster)

def test_in_event_listener_set_to_false_explicitly():
"""
Test when in_event_listener is explicitly set to False.
Should still return (False, False) if renderable is not set.
"""
DummyLocalContext.in_event_listener = DummyContextVar()
DummyLocalContext.in_event_listener.set(False)
DummyLocalContext.renderable = DummyContextVar()
codeflash_output = get_local_contexts(); result = codeflash_output # 3.24μs -> 998ns (225% faster)

def test_renderable_set_to_empty_string():
"""
Test when renderable is set to an empty string (which is not None).
Should return (False, True).
"""
DummyLocalContext.in_event_listener = DummyContextVar()
DummyLocalContext.renderable = DummyContextVar()
DummyLocalContext.renderable.set("")
codeflash_output = get_local_contexts(); result = codeflash_output # 3.12μs -> 958ns (226% faster)

def test_renderable_set_to_false():
"""
Test when renderable is set to False (which is not None).
Should return (False, True).
"""
DummyLocalContext.in_event_listener = DummyContextVar()
DummyLocalContext.renderable = DummyContextVar()
DummyLocalContext.renderable.set(False)
codeflash_output = get_local_contexts(); result = codeflash_output # 3.14μs -> 940ns (234% faster)

def test_in_event_listener_set_to_non_bool_value():
"""
Test when in_event_listener is set to a non-bool value (e.g., 123).
Should return (123, False).
"""
DummyLocalContext.in_event_listener = DummyContextVar()
DummyLocalContext.in_event_listener.set(123)
DummyLocalContext.renderable = DummyContextVar()
codeflash_output = get_local_contexts(); result = codeflash_output # 3.18μs -> 922ns (245% faster)

def test_renderable_set_to_object():
"""
Test when renderable is set to an object instance.
Should return (False, True).
"""
DummyLocalContext.in_event_listener = DummyContextVar()
DummyLocalContext.renderable = DummyContextVar()
DummyLocalContext.renderable.set({})
codeflash_output = get_local_contexts(); result = codeflash_output # 3.11μs -> 955ns (226% faster)

------------------- LARGE SCALE TEST CASES -------------------

def test_many_context_changes():
"""
Simulate changing context variables many times and ensure latest value is respected.
"""
DummyLocalContext.in_event_listener = DummyContextVar()
DummyLocalContext.renderable = DummyContextVar()
# Set and reset values multiple times
for i in range(100):
DummyLocalContext.in_event_listener.set(i % 2 == 0)
DummyLocalContext.renderable.set(i)
# Final set
DummyLocalContext.in_event_listener.set(True)
DummyLocalContext.renderable.set("final")
codeflash_output = get_local_contexts(); result = codeflash_output # 3.31μs -> 921ns (259% faster)

def test_large_number_of_contexts():
"""
Test with a large number of DummyLocalContext instances to ensure no cross-talk.
"""
# Simulate 500 different contexts
contexts = []
for i in range(500):
ctx = types.SimpleNamespace()
ctx.in_event_listener = DummyContextVar()
ctx.renderable = DummyContextVar()
ctx.in_event_listener.set(i % 2 == 0)
ctx.renderable.set(i if i % 3 == 0 else None)
contexts.append(ctx)
# Patch LocalContext for each context and test
for idx, ctx in enumerate(contexts):
DummyLocalContext.in_event_listener = ctx.in_event_listener
DummyLocalContext.renderable = ctx.renderable
expected = (idx % 2 == 0, idx % 3 == 0)
codeflash_output = get_local_contexts(); result = codeflash_output # 333μs -> 98.4μs (239% faster)

def test_performance_under_load():
"""
Test that get_local_contexts runs efficiently under a burst of calls.
"""
DummyLocalContext.in_event_listener = DummyContextVar()
DummyLocalContext.renderable = DummyContextVar()
DummyLocalContext.in_event_listener.set(True)
DummyLocalContext.renderable.set("busy")
# Call function 1000 times
for _ in range(1000):
codeflash_output = get_local_contexts(); result = codeflash_output # 648μs -> 190μs (241% faster)

codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

⏪ Replay Tests and Runtime
Test File::Test Function Original ⏱️ Optimized ⏱️ Speedup
test_pytest_testtest_components_py_testcomponentstest_audio_py_testcomponentstest_file_py_testcomponentst__replay_test_0.py::test_gradio_component_meta_get_local_contexts 185μs 56.3μs 230%✅

To edit these changes git checkout codeflash/optimize-get_local_contexts-mhv5g83b and push.

Codeflash Static Badge

The optimization eliminates a repeated import cost by moving the `from gradio.context import LocalContext` statement from inside the function to module scope. This simple change provides a **238% speedup** because:

**Key Performance Issue**: The original code performs a module import and attribute lookup on every function call. The line profiler shows this import taking 49.8% of the total execution time (1.92ms out of 3.86ms total).

**Optimization Applied**: By caching `LocalContext` as `_LocalContext` at module scope, we eliminate the repeated import overhead. The optimized version shows the import cost is completely removed from the function execution path.

**Why This Matters**: Looking at the function references, `get_local_contexts()` is called from the `updateable` decorator wrapper, which is applied to component constructors. This means the function executes every time a Gradio component is created or updated, making it a hot path where even microsecond improvements compound significantly.

**Performance Characteristics**: The test results show consistent 100-250% speedups across all scenarios:
- Basic cases: ~200-250% faster 
- Edge cases with different context values: ~200-250% faster
- Large-scale tests with loops: Up to 249% faster (337μs → 96.6μs)

**Impact on Workloads**: Since this function is in the component creation/update path, applications that create many components or frequently update them will see the most benefit. The optimization maintains identical behavior while reducing overhead in what appears to be a frequently-called utility function.

The optimization is particularly effective because Python's import mechanism involves dictionary lookups and module loading checks that add significant overhead when repeated thousands of times.
@codeflash-ai codeflash-ai bot requested a review from mashraf-222 November 11, 2025 22:35
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: High Optimization Quality according to Codeflash labels Nov 11, 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