⚡️ Speed up function _calculate_griddata by 43%
#165
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
📄 43% (0.43x) speedup for
_calculate_griddatainoptuna/visualization/matplotlib/_contour.py⏱️ Runtime :
582 milliseconds→407 milliseconds(best of18runs)📝 Explanation and details
The optimized code achieves a 42% speedup through several key algorithmic and data structure improvements:
1. Vectorized Array Operations
_calculate_griddata(). Instead of iterating throughzip(xaxis.values, yaxis.values)and checking each pair individually, the code creates NumPy arrays and uses vectorized masking:mask_valid = (xaxis_vals != None) & (yaxis_vals != None). This eliminates Python-level iteration overhead.2. Hash Map Lookups Instead of Linear Search
list.index()calls with O(1) dictionary lookups. The original code usedxaxis.indices.index(x_value)which is O(n), while the optimized version precomputesxindex_lookup = {val: idx for idx, val in enumerate(xaxis.indices)}for O(1) access.3. Vectorized Distance Calculations in
_create_zmap()np.argmin(np.abs(xi - x))calls per point to a fully vectorized operation using broadcasting:x_indices = np.abs(xi_arr[np.newaxis, :] - x_array[:, np.newaxis]). This computes all distances at once, dramatically reducing function call overhead.4. Sparse Matrix Construction Optimizations
_interpolate_zmap(), precomputedzmap_keys = set(zmap.keys())to avoid repeated dictionary key existence checks, and added the diagonal coefficient (4) explicitly rather than accumulating it through neighbor iterations.5. List Comprehension and Memory Layout Improvements
map()calls with list comprehensions ([float(x) for x in values]vslist(map(lambda x: float(x), values))) for better performance in modern Python.Performance Impact by Test Case:
The optimizations show consistent 42-44% improvements across all numerical and mixed-type test cases, with the largest gains in scenarios involving many data points where the vectorized operations and hash lookups provide maximum benefit. The two edge cases showing slower performance (empty values, same axis names) represent degenerate cases where the overhead of creating NumPy arrays outweighs the benefits, but these are uncommon in real usage.
Workload Suitability:
These optimizations are particularly effective for medium to large-scale contour plotting workloads typical in hyperparameter optimization visualization, where the function processes hundreds of trial points across multiple parameter dimensions.
✅ Correctness verification report:
🌀 Generated Regression Tests and Runtime
To edit these changes
git checkout codeflash/optimize-_calculate_griddata-mhobjf2zand push.