[swift-users] Large Structs, and COW.

Daniel Tartaglia danielt1263 at gmail.com
Fri Jan 22 15:52:48 CST 2016


> On Jan 22, 2016, at 4:35 PM, Joe Groff <jgroff at apple.com> wrote:
> 
>> 
>> On Jan 22, 2016, at 11:22 AM, Daniel Tartaglia via swift-users <swift-users at swift.org <mailto:swift-users at swift.org>> wrote:
>> 
>> If I have a large struct with lots of sub-structs and I assign to just one field of one of the sub-structs, will the system make a deep copy of the struct or a shallow copy where the unmodified portions of the object still point the same memory as the original struct?
>> 
>> In other words, given this code:
>> 
>> struct SubStruct {
>>     var a: Int = 0
>>     var b: Int = 0
>> }
>> 
>> struct VeryLarge {
>>     var subStructA = SubStruct()
>>     var subStructB = SubStruct()
>>     var subStructC = SubStruct()
>>     // lots of other stuff
>> }
>> 
>> func bar(var vl: VeryLarge) -> VeryLarge {
>>     vl.subStructA.a = 5
>>     return vl
>> }
>> 
>> let vl1 = VeryLarge()
>> let vl2 = bar(vl1)
>> 
>> Will vl2.subStructB be a copy of vl1.subStructB, or an entirely new object?
>> 
>> I’m worried about performance when making small changes to large objects.
> 
> Semantically, vl2 is always a distinct value, though how that ends up manifesting depends on the optimizer. By default, struct fields are stored in-line, like C structs, so sizeof(VeryLarge) will be sizeof(SubStruct) * 3 + sizeof(lots of other stuff), and a copy will be a full copy. If you want copy-on-write behavior, you currently have to implement it yourself, or build from already-implemented COW value types like Array. When structs pass a certain size threshold, the calling convention changes over to passing and returning them indirectly, though 'bar' will still naively introduce a copy to transfer the modified value from the argument to the result buffer. However, in optimized builds, if bar is inlined, then I'd expect this to ultimately reduce down to an in-place modification without copies, since vl1 is never used after assigning vl2.

Thanks for the reply. I’m asking because I am considering using a Redux system for an app I’m working on. One of the basic principles of Redux is that the entire app state be held in one struct, and I was worried about the system making a deep copy of the state struct every time I change any little variable.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160122/872ec018/attachment.html>


More information about the swift-users mailing list