Skip to content

perf(core): avoid config clones in prefix-filtered resolution#1091

Open
sauraww wants to merge 1 commit into
mainfrom
prefix-filter-optimisation
Open

perf(core): avoid config clones in prefix-filtered resolution#1091
sauraww wants to merge 1 commit into
mainfrom
prefix-filter-optimisation

Conversation

@sauraww

@sauraww sauraww commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Problem

Prefix-filtered configuration resolution deep-cloned the complete configuration, including all contexts, overrides, and dimensions, before applying the prefix filter. With the synthetic production-scale dataset of 468,006 contexts, this added significant allocation and cloning overhead to every prefix-filtered resolve.

Solution

Updated eval_config and eval_config_with_reasoning to use borrowed contexts and overrides for prefix-filtered resolution. Prefix filtering is now applied while collecting override keys, while the already-owned default configuration is filtered directly.

The benchmark now compares the previous cloned prefix path with the optimized borrowed path:

  • Previous cloned path: approximately 904.50 ms
  • Optimized borrowed path: approximately 55.535 ms
  • Improvement: approximately 16.3x faster, or a 93.9% reduction

The benchmark uses 468,006 synthetic contexts, 18 dimensions, 18 local cohorts, and 100 rotating queries. Detailed results are documented in docs/misc/PERF_ANALYSIS_RESOLUTION.md.

Environment variable changes

None.

BENCH_CONTEXTS remains an optional benchmark-only variable for overriding the default synthetic context count.

Pre-deployment activity

None.

Post-deployment activity

None.

API changes

No API or endpoint changes.

Endpoint | Method | Request body | Response body -- | -- | -- | -- N/A | N/A | No changes | No changes

Possible Issues in the future

Resolution still performs a linear scan over all contexts, and prefix matching checks each configured prefix against relevant keys. Large context datasets or many prefixes may therefore remain expensive.

The benchmark measures the core resolution path using synthetic data. It does not include provider/SDK overhead, network latency, cache initialization, or end-to-end P99 latency. Future improvements could include evaluation caching or indexing contexts to reduce the number of rules scanned per resolve.

Summary by CodeRabbit

  • Performance Improvements

    • Improved configuration resolution for requests using prefix filters.
    • Reduced unnecessary data processing when resolving filtered configuration values.
    • Preserved efficient resolution for unfiltered requests.
  • Documentation

    • Updated performance documentation with benchmark results comparing filtered and unfiltered resolution paths.

Copilot AI review requested due to automatic review settings July 10, 2026 19:20
@sauraww sauraww requested a review from a team as a code owner July 10, 2026 19:20
@semanticdiff-com

semanticdiff-com Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review changes with  SemanticDiff

Changed Files
File Status
  crates/superposition_core/benches/resolve.rs  19% smaller
  crates/superposition_core/src/config.rs  16% smaller
  docs/misc/PERF_ANALYSIS_RESOLUTION.md Unsupported file format

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

eval_config and eval_config_with_reasoning now filter prefixes directly while resolving overrides and default keys. Resolve benchmarks compare borrowed and cloned prefix paths, and performance documentation records the results.

Changes

Prefix-filtered resolution

Layer / File(s) Summary
Direct prefix filtering in config evaluation
crates/superposition_core/src/config.rs
Configuration evaluation uses HashSet prefix filters to select default and override keys during resolution without constructing a temporary Config.
Prefix resolution benchmark paths
crates/superposition_core/benches/resolve.rs
Criterion benchmarks compare unfiltered borrowed resolution, prefix-filtered borrowed resolution, and pre-filtered cloned resolution.
Performance analysis updates
docs/misc/PERF_ANALYSIS_RESOLUTION.md
Documentation describes the updated resolution paths and records prefix-filter benchmark estimates.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • juspay/superposition#1079: Earlier resolve hot-path and override-selection refactoring related to this prefix-filtering change.

Suggested reviewers: knutties, Datron, mahatoankitkumar

Poem

I’m a rabbit tuning keys with care,
Filtering prefixes through the air.
Borrowed paths now hop ahead,
Cloned paths trail where tests are led.
Benchmarks sparkle, docs explain—
Faster burrows through the chain!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: improving prefix-filtered resolution by avoiding config clones.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch prefix-filter-optimisation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves superposition_core configuration resolution performance for prefix-filtered requests by removing the full Config deep-clone and instead applying prefix filtering while collecting override keys and filtering the already-owned default config directly. Adds benchmark coverage and documents the before/after results for the prefix-filtered path.

Changes:

  • Update eval_config / eval_config_with_reasoning to resolve against borrowed contexts/overrides for both unfiltered and prefix-filtered requests.
  • Apply prefix filtering inside get_overrides (skip non-matching override keys) and filter default config keys before merging.
  • Expand the Criterion benchmark and performance analysis doc with prefix-filtered results and comparison against the previous cloned approach.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
docs/misc/PERF_ANALYSIS_RESOLUTION.md Updates the perf write-up to reflect the new borrowed prefix-filter path and adds prefix benchmark results.
crates/superposition_core/src/config.rs Refactors prefix-filtered resolution to avoid cloning full config; adds prefix-filter helpers and threads prefix filtering into override collection.
crates/superposition_core/benches/resolve.rs Adds prefix-filtered benchmark variants comparing pre-optimization cloned behavior vs optimized borrowed behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +22 to +24
let filter_prefixes: Option<HashSet<String>> = filter_prefixes
.filter(|prefixes| !prefixes.is_empty())
.map(HashSet::from_iter);
Comment on lines 129 to +142
match merge_strategy {
MergeStrategy::REPLACE => {
for (key, value) in overriden_value.iter() {
if !matches_prefix_filter(key, prefix_filter) {
continue;
}
required_overrides.insert(key.clone(), value.clone());
}
}
MergeStrategy::MERGE => {
for (key, value) in overriden_value.iter() {
if !matches_prefix_filter(key, prefix_filter) {
continue;
}

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
crates/superposition_core/src/config.rs (1)

22-41: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

eval_config and eval_config_with_reasoning are now identical — extract shared logic.

After this refactor, both functions have byte-for-byte identical bodies (same filter_prefixes conversion, get_overrides call with None callback, filter_config_keys_by_prefix, and merge_overrides_on_default_config). Any future bug fix or logic change must be applied in both places. Since eval_config_with_reasoning no longer adds reasoning metadata (confirmed by the test at line 210), it can simply delegate to eval_config.

♻️ Proposed delegation
 pub fn eval_config_with_reasoning(
     default_config: Map<String, Value>,
     contexts: &[Context],
     overrides: &HashMap<String, Overrides>,
     dimensions: &HashMap<String, DimensionInfo>,
     query_data: &Map<String, Value>,
     merge_strategy: MergeStrategy,
     filter_prefixes: Option<Vec<String>, // Optional prefix filtering
 ) -> Result<Map<String, Value>, String> {
-    let modified_query_data = evaluate_local_cohorts(dimensions, query_data);
-
-    let filter_prefixes: Option<HashSet<String>> = filter_prefixes
-        .filter(|prefixes| !prefixes.is_empty())
-        .map(HashSet::from_iter);
-
-    let overrides_map = get_overrides(
-        &modified_query_data,
-        contexts,
-        overrides,
-        &merge_strategy,
-        filter_prefixes.as_ref(),
-        None,
-    )?;
-
-    let mut result_config = match &filter_prefixes {
-        Some(prefixes) => filter_config_keys_by_prefix(default_config, prefixes),
-        None => default_config,
-    };
-    merge_overrides_on_default_config(&mut result_config, overrides_map, &merge_strategy);
-
-    Ok(result_config)
+    eval_config(
+        default_config,
+        contexts,
+        overrides,
+        dimensions,
+        query_data,
+        merge_strategy,
+        filter_prefixes,
+    )
 }

Also applies to: 55-74

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/superposition_core/src/config.rs` around lines 22 - 41, Extract the
duplicated implementation from eval_config_with_reasoning and make it delegate
directly to eval_config, preserving the existing parameters and return behavior.
Remove the repeated filter_prefixes conversion, get_overrides call, config
filtering, and merge logic so these operations remain maintained only in
eval_config.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/superposition_core/src/config.rs`:
- Around line 22-41: Extract the duplicated implementation from
eval_config_with_reasoning and make it delegate directly to eval_config,
preserving the existing parameters and return behavior. Remove the repeated
filter_prefixes conversion, get_overrides call, config filtering, and merge
logic so these operations remain maintained only in eval_config.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 04d172dc-6302-40a9-93c8-6877414bdced

📥 Commits

Reviewing files that changed from the base of the PR and between 77e840c and e491863.

📒 Files selected for processing (3)
  • crates/superposition_core/benches/resolve.rs
  • crates/superposition_core/src/config.rs
  • docs/misc/PERF_ANALYSIS_RESOLUTION.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants