-
Notifications
You must be signed in to change notification settings - Fork 712
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
don't Copy() self on Merge() #1728
Conversation
@2opremio I think my interpretation of the intended (and actual) Merge() semantics is correct, but I defer to your superior knowledge of scope internals. I have tested this by |
Nodes, Metrics, EdgeMetadata, MetadataTemplates could potentially also benefit from the same treatment, but are less straightforward than Report and Node. |
Is Merge() required to create deep copies or is it simply required not to modify self or other? My code in this PR, in common with a bunch of other the Merge() code I have come across, meets the former criteria. But there is also code which doesn't do that. For example Nodes.Merge() only deep-copies self but not other (in particular elements from other that are not present in self are only shallow-copied), and so only meets the latter criteria. If only the latter criteria is required, a whole bunch of easy, high-value optimisations are possible. |
@paulbellamy says it's the second. Which is just as well since otherwise some of the existing code would be wrong :) |
Thanks for this @rade! Calling Copy() inside Merge() at each level of the data structure means that objects were being unnecessarily copied
Unless I am missing something important, I believe Merge() is simply required not to modify self or other. In fact, as I mentioned above, Also, I believe that the benefit of this would be lower if all the data-structures where immutable internally (e.g. Metrics is still mutable) making copies essentially for free.
I don't immediately see how you can avoid copies with things like Metrics (based on a mutable map). |
Great, then we agree. |
It's the deep copy that is avoidable. |
But Metrics is a leaf of the data structure. The only optimization I see is using |
Sorry, I meant MetricTemplates. |
Oh, I see. All good. |
Merge() must not modify self or other; shallow-copying is sufficient to achieve that.
if e == nil && other == nil { | ||
return nil | ||
} | ||
result := make(MetadataTemplates, len(e)) |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
Note: (discussed offline with @rade ) See if we can get rid of all the |
LGTM |
Merge() is always returning a copy, so there is no need to Copy() struct fields first before calling Merge() on them.
This reduces GC pressure (#1010) and helps overall app performance (#1457).