Avoid mutating user passed in options #994
Merged
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.
This fixes #924 and #903
Here's an issue demonstration borrowed from #924
There are 2 factors that cause the issue:
Eventobject.Eventobject, processors likeRemoveCircularReferencesuse mutation methods likeHash#merge!to save memory allocation.First Attempt - Drop methods that mutate the data
A quick fix is to change the step
2to just use methods likeHash#merge. But this can have a significant impact on the memory allocation (about 16~17% more) perRaven#capture_messagecall.Here's an example:
Code Change
Allocation before the change
Allocation after the change + comparsion
Allocation Comparison
A More Allocation-Efficient Solution - Duplicate user-passed data (options)
By duplicating user-passed objects, we can avoid the later mutations from changing the data user has. And because user-passed data usually won't be too big, we won't allocate too much memory by doing this. Here's an example:
Code Change
Allocation before the change
Allocation after the change
Allocation Comparison
As you can see, this approach only allocates about 2xx bytes more of memory. So it's the approach I chose in this PR.
Question - Why making our own
deep_dupextension instead of usingActiveSupport's?deep_dupis very stable and hasn't changed for 3 years. So it's not a great risk that we'll be out-of-sync on it.