-
Notifications
You must be signed in to change notification settings - Fork 15
Open
Description
Requesting a method to evaluate multiple features with a single shared UserContext to reduce memory usage when evaluating many features for the same user.
Problem Statement
When evaluating multiple features for the same user, we create a UserContext once and reuse it across evaluations. However, each call to evalFeature() or getFeatureValue() may create internal copies or duplicate data structures, leading to:
- Higher memory usage when evaluating 50-100+ features per request
- Unnecessary object allocations
- Potential performance overhead from repeated context processing
Use Case
We have a high-throughput service that evaluates 50-100 features per user request. Currently, we:
// Create UserContext once
UserContext userContext = new UserContext.UserContextBuilder()
.build()
.witAttributesJson(attributesJson);
// Evaluate multiple features sequentially or in parallel
for (String featureName : featureNames) {
FeatureResult<Object> result = client.evalFeature(
featureName,
Object.class,
userContext // Same context reused
);
// Process result...
}While UserContext is immutable and thread-safe, the SDK may still create internal copies or process the context multiple times.
Current Behavior
- Each
evalFeature()call processes theUserContextindependently - No explicit optimization for batch evaluation scenarios
- Memory usage scales linearly with the number of features evaluated
Proposed Solution
Add a batch evaluation method that:
- Accepts a list of feature keys and a single
UserContext - Internally optimizes context processing (parse attributes once, reuse parsed data)
- Returns a map of feature keys to their evaluated results
- Minimizes memory allocations by sharing internal data structures
Proposed API:
// Option 1: New method on GrowthBookClient
Map<String, FeatureResult<Object>> evalFeatures(
List<String> featureKeys,
Class<Object> valueTypeClass,
UserContext userContext
);
// Option 2: Builder pattern for batch operations
BatchEvaluator batchEvaluator = client.createBatchEvaluator(userContext);
Map<String, FeatureResult<Object>> results = batchEvaluator
.evalFeatures(featureKeys, Object.class);Benefits
- Memory efficiency: parse and process
UserContextonce for multiple features - Performance: reduce redundant context processing
- API clarity: explicit batch evaluation method
- Backward compatible: existing single-feature methods remain unchanged
Example Implementation (Pseudo-code)
public Map<String, FeatureResult<ValueType>> evalFeatures(
List<String> featureKeys,
Class<ValueType> valueTypeClass,
UserContext userContext
) {
// Parse attributes once
Map<String, Object> parsedAttributes = parseAttributes(userContext.getAttributesJson());
// Pre-compute common context data
EvaluationContext evalContext = buildEvaluationContext(userContext, parsedAttributes);
// Evaluate all features using shared context
Map<String, FeatureResult<ValueType>> results = new HashMap<>();
for (String featureKey : featureKeys) {
results.put(featureKey, evaluateFeature(featureKey, valueTypeClass, evalContext));
}
return results;
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels