perf: Optimize field access to eliminate memory allocations (Accessor layer)#6113
Open
skcc321 wants to merge 1 commit intomongodb:masterfrom
Open
perf: Optimize field access to eliminate memory allocations (Accessor layer)#6113skcc321 wants to merge 1 commit intomongodb:masterfrom
skcc321 wants to merge 1 commit intomongodb:masterfrom
Conversation
Implement a strategy pattern for field access that achieves zero memory allocations on repeated reads through intelligent caching of demongoized values. Key optimizations: - Introduce Accessor and CachingAccessor classes to encapsulate field access logic - Cache demongoized values to eliminate repeated type conversions - Invalidate cache only when fields are modified - Handle edge cases: lazy defaults, localized fields, resizable values - Add configuration flag cache_attribute_values (default: false) Performance improvements: - Zero allocations for cached field reads (String, Integer, Float, etc.) - Proper change tracking for resizable fields (Arrays, Hashes) - Thread-safe concurrent access for projections Testing: - Add comprehensive performance_spec.rb with 53 test cases - Cover allocation optimizations, cache invalidation, edge cases - Verify behavior with database-loaded documents and atomic operations - Test concurrent access patterns This optimization maintains backward compatibility while providing significant performance gains when enabled.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Optimize field access to eliminate memory allocations by introducing Accessor layer for caching.
Summary
Introduces a clean, extensible Strategy Pattern architecture for attribute access in Mongoid, achieving zero memory allocations on subsequent field reads when caching is
enabled.
Motivation
Attribute reads in Mongoid currently perform type conversion (demongoization) on every access, causing unnecessary allocations and performance overhead. For applications with
frequent attribute access patterns, this can lead to significant memory pressure and reduced throughput.
Example of the problem:
This PR eliminates these repeated allocations through an opt-in caching strategy.
Performance Impact
100% allocation reduction across all native MongoDB field types:
All performance tests verified with
allocation_statsgem.Implementation
This PR uses the Strategy Pattern with pluggable accessor classes and opt-in configuration.
Core Architecture
The implementation uses two accessor strategies:
Mongoid::Attributes::Accessor- Base accessor with no cachingMongoid::Attributes::CachingAccessor- Performance-optimized accessorConcurrent::MapConfiguration
Enable caching globally (opt-in):
Or in
mongoid.yml:Key Features
Concurrent::Mapdatabase_field_name,cleanse_localized_field_names, andtraverse_association_treeAdvantages of this approach:
Trade-offs:
Safety Guarantees
demongoize()on first access - no unsafe shortcutsTest Coverage
tests covering:
.only,.without)Backward Compatibility
✅ 100% backward compatible
With
cache_attribute_values = false(the default):The implementation adds only a single method call layer with negligible overhead.
Example Usage
Memory Considerations
When
cache_attribute_valuesis enabled:Concurrent::Mapfor the cacheFor applications that keep many document instances in memory (thousands or more), this additional per-document and per-field state can lead to noticeable memory overhead.
Enable this option only when the performance benefits of avoiding repeated type conversions justify the extra memory use for your workload.
Breaking Changes
None. Internal optimizations only.
Related Issues
Addresses performance concerns with repeated attribute access patterns in high-throughput applications.
Related
See PR #6112 for an alternative direct caching implementation that is always enabled.