<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On May 6, 2017, at 9:33 PM, Kelvin Ma via swift-users &lt;<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class=""><div class=""><font face="monospace,monospace" class="">If I have a “large” struct like<br class=""><br class="">struct Vertex<br class="">{<br class="">&nbsp;&nbsp;&nbsp; let x:Double, y:Double<br class="">&nbsp;&nbsp;&nbsp; var r:Int, g:Int, b:Int<br class="">&nbsp;&nbsp;&nbsp; let s:Double, t:Double<br class="">&nbsp;&nbsp;&nbsp; var selected:Bool<br class="">}<br class=""><br class=""></font></div><div class=""><font face="monospace,monospace" class="">and I want to pass it to a function without modifying it like<br class=""></font></div><div class=""><font face="monospace,monospace" class=""><br class="">func taxicab_distance(_ v1:Vertex, _ v2:Vertex) -&gt; Double<br class="">{<br class="">&nbsp;&nbsp;&nbsp; return v2.x - v1.x + v2.y - v1.y<br class="">}<br class=""><br class=""></font></div><div class=""><font face="monospace,monospace" class="">Will the entire struct Vertex get copied and pushed onto the stack, or will only the relevant members be passed to the function?<br class=""><br class=""></font></div><div class=""><font face="monospace,monospace" class="">In other words, does the compiler know to optimize this call down to<br class=""><br class=""></font><font face="monospace,monospace" class="">func taxicab_distance(v2x:Double, v1x:Double, v2y:Double, v1y:Double) -&gt; Double<br class="">{<br class="">&nbsp;&nbsp;&nbsp; return v2x - v1x + v2y - v1y<br class="">}</font></div></div></div></div></blockquote><br class=""></div><div>When passed as an argument, a struct is recursively broken up into individual primitives, and each of those is passed in separate arguments. (The primitive types in question are mostly special "builtin" types which are wrapped by standard library types like `Int` and `Double`.) As far as I'm aware, there is no optimization that removes unused parts of the struct. That means this would be passed as something like:</div><div><br class=""></div><div>func taxicab_distance(_ v1.x._value: Builtin.Float64, _ v1.y._value: Builtin.Float64, _ v1.r._value: Builtin.Int64, _ v1.g._value: Builtin.Int64, _ v1.b._value: Builtin.Int64, _ v1.s._value: Builtin.Float64, _ v1.t._value: Builtin.Float64, _ v1.selected._value: Builtin.Int1, _ v2.x._value: Builtin.Float64, _ v2.y._value: Builtin.Float64, _ v2.r._value: Builtin.Int64, _ v2.g._value: Builtin.Int64, _ v2.b._value: Builtin.Int64, _ v2.s._value: Builtin.Float64, _ v2.t._value: Builtin.Float64, _ v2.selected._value: Builtin.Int1) -&gt; Builtin.Float64 { … }</div><div><br class=""></div><div>Because of this, it may sometimes make sense to convert large structs into copy-on-write types by hand—basically, make a struct which wraps an inner class type, guarding all mutations with an `isUniquelyReferenced(_:)` check. (You're right that there's no implicit copy-on-write behavior in structs currently—when a struct has copy-on-write behavior, it has been manually implemented that way.)</div><div><br class=""></div><div>Note that this may not always be the case: There's a built-in copy-on-write optimization which will soon come to instances which have been cast to a protocol type, and the "resilient" structs planned for a future version of Swift will probably be passed by reference in some way. But I believe that's the state of things in Swift 3.</div><br class=""><div class="">
<span class="Apple-style-span" style="border-collapse: separate; font-variant-ligatures: normal; font-variant-east-asian: normal; font-variant-position: normal; line-height: normal; border-spacing: 0px;"><div class=""><div style="font-size: 12px; " class="">--&nbsp;</div><div style="font-size: 12px; " class="">Brent Royal-Gordon</div><div style="font-size: 12px; " class="">Architechies</div></div></span>

</div>
<br class=""></body></html>