perf: optimize copy on write attributes #74
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.
Requirements
Related issues
none
Describe the solution you've provided
i have modified the copy on write mechanism for custom attributes to avoid having to copy the whole attribute map. instead i chain to the parent map. this does not change the public API or outwards behavior. the implementation was complicated because of the need to support the "remove" operation. additionally, i leveraged the equals and hashCode of Map. note: hashCode from Map is not order dependent since it uses addition across all of the entries and addition is commutative.
Describe alternatives you've considered
i was also playing around with a lazy LDValue provider such that we do not need to create all of the attributes if we do not use them but that seemed like a lot of rework and hard to do in a codebase currently targeting jdk 7.
Additional context
i was doing flame graph analysis and found that there were a lot of copies of the hash maps going on, so i thought i could try to eliminate those copies. my use case involves the case in the new test case i added, but it is located in a hotspot in my codebase. the parent context has dozens of attributes and is shared across multiple evaluations. however the child contexts add on only a handful of attributes. the current implementation was copying over all of the attributes for each new build since the parent context was tainted. this root/parent chaining and reuse is a common paradigm over the codebase