<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On May 18, 2017, at 12:38 PM, Anders Kierulf <<a href="mailto:anders@smartgo.com" class="">anders@smartgo.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">And you don’t want to create a temp copy:<br class=""><br class=""> var tupleMemory = letTuple<br class=""> get(&tupleMemory, at: 2)<br class=""><br class="">In this case, the letTuple->UnsafeRawPointer conversion is likely going to create that copy anyway in order to give the tuple a memory address. A slightly more compelling example would be:<br class=""><br class="">struct S {<br class=""> var tuple: (Int, Int, Int, Int, Int, Int)<br class="">}<br class=""><br class="">func foo(s: S) -> Int {<br class=""> var tupleMemory = s.tuple // was s.t, should be s.tuple [AK]<br class=""> return get(&tupleMemory, at: 2) // fails: wrong type<br class="">}<br class=""><br class="">Are you more concerned that the copy won't be optimized away or that you need the extra line of code?<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">My main concern is performance. In my code, the tuple is often 380 words long, so a copy completely kills performance. This part of my code is performance critical, which is why I can’t just use Swift’s standard Array type.</span></div></div></blockquote></div><div class=""><br class=""></div>I agree with your proposed language changes, but there’s really a larger issue. Until we have move-only types and ‘shared’ argument conventions, I’m afraid that passing around a large struct, or even implicitly converting it to a pointer creates copies. `let` doesn’t give you a no-copy guarantee. If those copies aren’t already optimized at -O, it’s possible the optimizer could be improved to handle your cases. However, I don’t think you should rely on that. For now, until the ownership work is further along, the best way to avoid copies is to embrace mutability. Declare your large value types as `var` and always pass them `inout`.<div class=""><br class=""></div><div class="">I just noticed this bug, which has shows why the type system can make a copy impossible to avoid.</div><div class=""><a href="https://bugs.swift.org/browse/SR-4581" class="">https://bugs.swift.org/browse/SR-4581</a></div><div class="">If you don’t care about conforming to UnsafeMutableCollection and implementing subscript { get } conformance, maybe you can avoid that problem.</div><div class=""><div class=""><br class=""></div><div class="">Another option is to use indirect reference-counted storage for your fixed array, just like Array, so incidental copies aren’t expensive.</div><div class=""><br class=""></div><div class="">-Andy</div></div></body></html>