feat: Implement evalFeatures() for optimized batch evaluation#185
feat: Implement evalFeatures() for optimized batch evaluation#185vazarkevych wants to merge 3 commits intogrowthbook:mainfrom
Conversation
| * @param userContext The user context (will be processed once) | ||
| * @param <ValueType> The type of the result value | ||
| * @return A map where keys are feature keys and values are FeatureResult objects | ||
| */ |
There was a problem hiding this comment.
Memory Issue: EvaluationContext created per feature
The current implementation creates a new EvaluationContext inside the loop for every feature evaluation. Each EvaluationContext holds a reference to GlobalContext, which contains the entire parsed features map and saved groups (potentially hundreds of MBs). When evaluating thousands of features in parallel batches, this results in thousands of EvaluationContext copies being held in memory simultaneously (10GB+ observed), causing excessive memory pressure and GC overhead.
Root cause: EvaluationContext is created per feature instead of being reused across all features in the batch.
Solution: Create EvaluationContext once outside the loop and reuse it for all feature evaluations in the batch. Since we've already merged attributes once into optimizedUserContext, the same EvaluationContext can safely be reused for evaluating all features, reducing memory allocation from O(n * size(GlobalContext)) to O(size(GlobalContext)) per batch.
There was a problem hiding this comment.
Thanks for the review. I have moved EvaluationContext out of the loop and reuse it, but after each evaluation I set a new StackContext to prevent circular dependency.
# Conflicts: # lib/src/main/java/growthbook/sdk/java/multiusermode/GrowthBookClient.java
Summary
In this PR we have Implemented batch feature evaluation API to optimize memory usage when evaluating multiple features for the same user.
Changes
evalFeatures()method toGrowthBookClientfor batch evaluationevalFeatures()method toGrowthBookfor API consistencymergeAttributes()helper method to avoid code duplication