Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
None
-
Untriaged
-
1
-
Unknown
Description
plasma.go constructors New(), New2(), New3() all accept argument cfg Config, which is a struct, therefore it is being passed by value not by reference. This means each call, and each child this is passed to that does the same thing, makes a new shallow copy of the entire Config struct. By my count this struct currently contains 113 fields, so these copies are doing a lot of extra CPU work and consuming significant stack.
E.g. a call to New(cfg) triggers the following copies (at least the first 5, and possibly up to 7, assuming none of the great-grandchildren copy it further):
- New(cfg) – arg copied on call
- New2(cfg, ...) – copied to child call
- New3(cfg, ...) – copied to grandchild call
- applyConfigDefaults(cfg, ...) – copied to first great-grandchild call
- cfg = applyConfigDefaults(...) – and copied again assigning the returned copy back to New3's cfg variable
- doRecovery(..., cfg, ...) – copied to second great-grandchild if this call is made
- newPlasmaSkeleton(cfg, ...) – copied to third great-grandchild if this call is made
Attachments
Activity
Field | Original Value | New Value |
---|---|---|
Assignee | John Liang [ jliang ] | Dmitriy Kalugin-Balashov [ dmitriy.kalugin-balashov ] |
Labels | plasma |
Description |
plasma.go constructors *New(), New2(), New3()* all accept argument *cfg Config*, which is a struct, therefore it is being passed by value not by reference. This means each call, and each child this is passed to that does the same thing, makes a new shallow copy of the entire Config struct. By my count this struct currently contains 113 fields, so these copies are doing a lot of extra CPU work and consuming significant stack.
E.g. a call to New(cfg) triggers the following copies (at least the first 5, and possibly up to 7, assuming none of the grandchildren copy it further): # New({color:#ff0000}*cfg*{color}) – arg copied on call # New2({color:#ff0000}*cfg*{color}, ...) – copied to child call # New3({color:#ff0000}*cfg*{color}, ...) – copied to grandchild call # applyConfigDefaults({color:#ff0000}*cfg*{color}, ...) – copied to first grandchild call # {color:#ff0000}*cfg*{color} = applyConfigDefaults(...) – and copied again assigning the returned copy back to New3's cfg variable # doRecovery(..., {color:#ff0000}*cfg*{color}, ...) – copied to second grandchild if this call is made # newPlasmaSkeleton({color:#ff0000}*cfg*{color}, ...) – copied to third grandchild if this call is made |
plasma.go constructors *New(), New2(), New3()* all accept argument *cfg Config*, which is a struct, therefore it is being passed by value not by reference. This means each call, and each child this is passed to that does the same thing, makes a new shallow copy of the entire Config struct. By my count this struct currently contains 113 fields, so these copies are doing a lot of extra CPU work and consuming significant stack.
E.g. a call to New(cfg) triggers the following copies (at least the first 5, and possibly up to 7, assuming none of the great-grandchildren copy it further): # New({color:#ff0000}*cfg*{color}) – arg copied on call # New2({color:#ff0000}*cfg*{color}, ...) – copied to child call # New3({color:#ff0000}*cfg*{color}, ...) – copied to grandchild call # applyConfigDefaults({color:#ff0000}*cfg*{color}, ...) – copied to first great-grandchild call # {color:#ff0000}*cfg*{color} = applyConfigDefaults(...) – and copied again assigning the returned copy back to New3's cfg variable # doRecovery(..., {color:#ff0000}*cfg*{color}, ...) – copied to second great-grandchild if this call is made # newPlasmaSkeleton({color:#ff0000}*cfg*{color}, ...) – copied to third great-grandchild if this call is made |
Status | Open [ 1 ] | In Progress [ 3 ] |
Resolution | Fixed [ 1 ] | |
Status | In Progress [ 3 ] | Resolved [ 5 ] |
Labels | plasma | plasma request-dev-verify |
Status | Resolved [ 5 ] | Closed [ 6 ] |