Skip to content

Conversation

@codeflash-ai
Copy link

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

📄 8% (0.08x) speedup for GsContentApi._build_parameters_dict in gs_quant/api/gs/content.py

⏱️ Runtime : 1.11 milliseconds 1.04 milliseconds (best of 149 runs)

📝 Explanation and details

Optimization rationale:

  • The original code sorts every value unnecessarily, even if there is only one or zero items (where sorting is a no-op but incurs overhead).
  • This rewrite skips calling sorted() on values with zero or one item, reducing unnecessary function calls and short-lived allocations, which measurably optimizes runtime for commonly empty or singleton values.
  • All code style, type annotations, comments, return type, and logic are preserved.
  • OrderedDict is still used on the final result, ensuring output ordering remains unchanged.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 44 Passed
⏪ Replay Tests 3 Passed
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
🌀 Generated Regression Tests and Runtime
from collections import OrderedDict

# imports
import pytest
from gs_quant.api.gs.content import GsContentApi

# unit tests

# 1. Basic Test Cases

def test_single_parameter_single_value():
    # Test with one key and one value
    codeflash_output = GsContentApi._build_parameters_dict(foo=['bar']); result = codeflash_output # 2.63μs -> 2.47μs (6.56% faster)

def test_single_parameter_multiple_values():
    # Test with one key and multiple values (should be sorted)
    codeflash_output = GsContentApi._build_parameters_dict(foo=['baz', 'bar', 'qux']); result = codeflash_output # 2.58μs -> 2.76μs (6.27% slower)

def test_multiple_parameters_single_value_each():
    # Test with multiple keys, one value each
    codeflash_output = GsContentApi._build_parameters_dict(a=['1'], b=['2'], c=['3']); result = codeflash_output # 3.40μs -> 2.86μs (18.8% faster)

def test_multiple_parameters_multiple_values_each():
    # Test with multiple keys, multiple values each
    codeflash_output = GsContentApi._build_parameters_dict(
        alpha=['z', 'x', 'y'],
        beta=['b', 'a', 'c'],
        gamma=['g', 'h']
    ); result = codeflash_output # 3.49μs -> 3.58μs (2.46% slower)

def test_parameter_with_empty_list():
    # Should not include parameters with empty lists
    codeflash_output = GsContentApi._build_parameters_dict(foo=[], bar=['baz']); result = codeflash_output # 2.34μs -> 2.21μs (6.07% faster)

def test_parameter_with_none_value():
    # Should not include parameters with None value
    codeflash_output = GsContentApi._build_parameters_dict(foo=None, bar=['baz']); result = codeflash_output # 2.43μs -> 2.13μs (14.3% faster)

def test_parameter_with_false_value():
    # Should not include parameters with False value
    codeflash_output = GsContentApi._build_parameters_dict(foo=False, bar=['baz']); result = codeflash_output # 2.40μs -> 2.12μs (12.9% faster)

def test_parameter_with_zero_value():
    # Should not include parameters with 0 value
    codeflash_output = GsContentApi._build_parameters_dict(foo=0, bar=['baz']); result = codeflash_output # 2.24μs -> 2.01μs (11.4% faster)

def test_parameter_with_empty_string_value():
    # Should not include parameters with empty string value
    codeflash_output = GsContentApi._build_parameters_dict(foo='', bar=['baz']); result = codeflash_output # 2.32μs -> 2.03μs (14.4% faster)

def test_parameter_with_nonempty_string_value():
    # Should not include non-list, non-iterable values (should not extend)
    # But per implementation, if value is truthy, tries to sort and extend
    # Strings are iterable, so this will sort the string and extend as chars
    codeflash_output = GsContentApi._build_parameters_dict(foo='baz', bar=['qux']); result = codeflash_output # 3.28μs -> 3.16μs (3.96% faster)

# 2. Edge Test Cases

def test_no_parameters():
    # Should return empty OrderedDict
    codeflash_output = GsContentApi._build_parameters_dict(); result = codeflash_output # 1.21μs -> 1.17μs (3.43% faster)

def test_all_parameters_none_or_empty():
    # Should return empty OrderedDict
    codeflash_output = GsContentApi._build_parameters_dict(a=None, b=[], c='', d=False, e=0); result = codeflash_output # 1.90μs -> 1.85μs (2.53% faster)

def test_parameter_with_tuple_value():
    # Should handle tuple values (sorted)
    codeflash_output = GsContentApi._build_parameters_dict(foo=('baz', 'bar', 'qux')); result = codeflash_output # 2.60μs -> 2.65μs (1.59% slower)

def test_parameter_with_set_value():
    # Should handle set values (sorted)
    codeflash_output = GsContentApi._build_parameters_dict(foo={'baz', 'bar', 'qux'}); result = codeflash_output # 2.85μs -> 2.85μs (0.245% slower)

def test_parameter_with_dict_value():
    # Should handle dict values (sorted keys)
    codeflash_output = GsContentApi._build_parameters_dict(foo={'b': 1, 'a': 2}); result = codeflash_output # 2.50μs -> 2.61μs (4.22% slower)




def test_parameter_with_bytes_value():
    # Should treat bytes as iterable and sort as ints
    codeflash_output = GsContentApi._build_parameters_dict(foo=b'cab'); result = codeflash_output # 3.33μs -> 3.28μs (1.62% faster)

def test_parameter_with_mixed_types():
    # Should handle multiple types, skip falsy
    codeflash_output = GsContentApi._build_parameters_dict(
        foo=['bar'], bar=None, baz=(), qux=['quux', 'corge']
    ); result = codeflash_output # 3.46μs -> 3.38μs (2.39% faster)

def test_parameter_with_list_of_ints():
    # Should sort list of ints
    codeflash_output = GsContentApi._build_parameters_dict(foo=[3, 1, 2]); result = codeflash_output # 2.57μs -> 2.62μs (2.14% slower)



def test_large_number_of_parameters():
    # Test scalability with many parameters
    kwargs = {f'param{i}': [str(i)] for i in range(1000)}
    codeflash_output = GsContentApi._build_parameters_dict(**kwargs); result = codeflash_output # 261μs -> 226μs (15.6% faster)
    for i in range(1000):
        pass

def test_large_list_values():
    # Test with large list value
    large_list = list(range(1000, 0, -1))  # Descending order
    codeflash_output = GsContentApi._build_parameters_dict(foo=large_list); result = codeflash_output # 9.10μs -> 9.15μs (0.579% slower)

def test_large_mixed_parameters_some_none():
    # Test with many parameters, some None or empty
    kwargs = {f'param{i}': [i] if i % 2 == 0 else None for i in range(1000)}
    codeflash_output = GsContentApi._build_parameters_dict(**kwargs); result = codeflash_output # 157μs -> 140μs (12.0% faster)
    for i in range(0, 1000, 2):
        pass

def test_large_list_of_strings():
    # Test with large list of strings
    large_list = [str(i) for i in range(1000)]
    codeflash_output = GsContentApi._build_parameters_dict(foo=large_list); result = codeflash_output # 21.3μs -> 21.3μs (0.305% slower)

def test_large_list_of_duplicates():
    # Test with large list with duplicates
    large_list = ['a'] * 1000
    codeflash_output = GsContentApi._build_parameters_dict(foo=large_list); result = codeflash_output # 10.2μs -> 10.4μs (2.65% slower)

def test_large_list_with_mixed_truthy_falsy():
    # Test with large list, some falsy values inside (should not filter inside)
    large_list = [0, '', None, 'a', 'b', False, 'c']
    codeflash_output = GsContentApi._build_parameters_dict(foo=large_list); result = codeflash_output
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
#------------------------------------------------
from collections import OrderedDict

# imports
import pytest
from gs_quant.api.gs.content import GsContentApi

# unit tests

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

def test_single_key_single_value():
    # Single key with a single value in a list
    codeflash_output = GsContentApi._build_parameters_dict(foo=['bar']); result = codeflash_output # 3.30μs -> 3.02μs (9.06% faster)

def test_multiple_keys_single_value_each():
    # Multiple keys, each with a single value
    codeflash_output = GsContentApi._build_parameters_dict(a=['x'], b=['y']); result = codeflash_output # 3.11μs -> 2.78μs (11.9% faster)

def test_multiple_keys_multiple_values():
    # Multiple keys, each with multiple values
    codeflash_output = GsContentApi._build_parameters_dict(a=['x', 'z'], b=['y', 'w']); result = codeflash_output # 2.84μs -> 2.97μs (4.37% slower)

def test_value_is_sorted():
    # Values should be sorted
    codeflash_output = GsContentApi._build_parameters_dict(a=['z', 'x', 'y']); result = codeflash_output # 2.58μs -> 2.56μs (0.664% faster)

def test_none_value_filtered():
    # Key with value None should be filtered out
    codeflash_output = GsContentApi._build_parameters_dict(foo=None, bar=['baz']); result = codeflash_output # 2.48μs -> 2.18μs (14.1% faster)

def test_empty_list_filtered():
    # Key with empty list should be filtered out
    codeflash_output = GsContentApi._build_parameters_dict(foo=[], bar=['baz']); result = codeflash_output # 2.38μs -> 2.05μs (16.2% faster)

def test_all_none_and_empty_filtered():
    # All keys have None or empty list, should return empty OrderedDict
    codeflash_output = GsContentApi._build_parameters_dict(foo=None, bar=[], baz=None); result = codeflash_output # 1.69μs -> 1.68μs (0.774% faster)

def test_no_kwargs():
    # No kwargs passed, should return empty OrderedDict
    codeflash_output = GsContentApi._build_parameters_dict(); result = codeflash_output # 1.08μs -> 1.07μs (1.31% faster)

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

def test_key_with_false_value():
    # Key with boolean False should be filtered out
    codeflash_output = GsContentApi._build_parameters_dict(foo=False, bar=['baz']); result = codeflash_output # 2.55μs -> 2.21μs (15.4% faster)

def test_key_with_empty_string():
    # Key with empty string should be filtered out
    codeflash_output = GsContentApi._build_parameters_dict(foo='', bar=['baz']); result = codeflash_output # 2.40μs -> 2.19μs (9.62% faster)

def test_key_with_zero():
    # Key with zero should be filtered out
    codeflash_output = GsContentApi._build_parameters_dict(foo=0, bar=['baz']); result = codeflash_output # 2.32μs -> 2.17μs (7.01% faster)


def test_key_with_tuple_value():
    # Tuple values should be sorted and extended as list
    codeflash_output = GsContentApi._build_parameters_dict(foo=('z', 'x', 'y')); result = codeflash_output # 3.37μs -> 3.50μs (3.69% slower)

def test_key_with_set_value():
    # Set values should be sorted and extended as list
    codeflash_output = GsContentApi._build_parameters_dict(foo={'z', 'x', 'y'}); result = codeflash_output # 3.00μs -> 3.00μs (0.067% slower)



def test_duplicate_values_in_list():
    # Duplicate values should be preserved and sorted
    codeflash_output = GsContentApi._build_parameters_dict(foo=['b', 'a', 'b']); result = codeflash_output # 3.02μs -> 3.07μs (1.76% slower)

def test_order_of_keys_preserved():
    # The order of keys in kwargs should be preserved in OrderedDict
    codeflash_output = GsContentApi._build_parameters_dict(a=['x'], b=['y'], c=['z']); result = codeflash_output # 3.36μs -> 3.03μs (11.0% faster)

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

def test_large_number_of_keys():
    # Large number of keys, each with a single value
    kwargs = {f'key_{i}': [str(i)] for i in range(1000)}
    codeflash_output = GsContentApi._build_parameters_dict(**kwargs); result = codeflash_output # 261μs -> 229μs (13.9% faster)
    # Each value should be a single-element list with the string of its index
    for i in range(1000):
        pass

def test_large_number_of_values_per_key():
    # Single key with a large number of values
    values = [str(i) for i in range(1000, 0, -1)]  # descending order
    codeflash_output = GsContentApi._build_parameters_dict(big_key=values); result = codeflash_output # 18.9μs -> 19.3μs (1.94% slower)

def test_large_number_of_keys_and_values():
    # Many keys, each with many values
    kwargs = {f'key_{i}': [str(j) for j in range(10)] for i in range(100)}
    codeflash_output = GsContentApi._build_parameters_dict(**kwargs); result = codeflash_output # 36.2μs -> 37.0μs (1.99% slower)
    for i in range(100):
        pass

def test_large_number_of_none_and_empty_filtered():
    # Many keys, but only a few have values
    kwargs = {f'key_{i}': None if i % 2 == 0 else [] for i in range(1000)}
    # Add one valid key
    kwargs['valid'] = ['ok']
    codeflash_output = GsContentApi._build_parameters_dict(**kwargs); result = codeflash_output # 54.0μs -> 52.1μs (3.59% faster)

def test_performance_large_scale():
    # Performance test for large input (not strict timing, just runs without error)
    kwargs = {f'key_{i}': [str(j) for j in range(10)] for i in range(500)}
    codeflash_output = GsContentApi._build_parameters_dict(**kwargs); result = codeflash_output # 174μs -> 184μs (5.67% slower)
    for i in range(500):
        pass
# 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_gs_quanttestapitest_content_py_gs_quanttestanalyticstest_workspace_py_gs_quanttesttimeseriest__replay_test_0.py::test_gs_quant_api_gs_content_GsContentApi__build_parameters_dict 8.85μs 8.71μs 1.63%✅

To edit these changes git checkout codeflash/optimize-GsContentApi._build_parameters_dict-mhb12yx7 and push.

Codeflash

**Optimization rationale:**

- The original code sorts every value unnecessarily, even if there is only one or zero items (where sorting is a no-op but incurs overhead).
- This rewrite skips calling `sorted()` on values with zero or one item, reducing unnecessary function calls and short-lived allocations, which measurably optimizes runtime for commonly empty or singleton values.  
- All code style, type annotations, comments, return type, and logic are preserved.  
- `OrderedDict` is still used on the final result, ensuring output ordering remains unchanged.
@codeflash-ai codeflash-ai bot requested a review from mashraf-222 October 28, 2025 20:37
@codeflash-ai codeflash-ai bot added ⚡️ codeflash Optimization PR opened by Codeflash AI 🎯 Quality: Medium Optimization Quality according to Codeflash labels Oct 28, 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