<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 class="">If Swift is to be a systems language someday, then we also need to be able to write (parts of) Accelerate in Swift.</div><div class=""><br class=""></div><div class="">– Steve</div><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 11, 2015, at 11:27 AM, Erica Sadun via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;">For many of these number-crunching performance-stretching scenarios, many I suggest once again, that if you're doing serious number crunching that Accelerate or similar approaches is to be preferred? As for c-style-for vs while, the two are mechanically convertible.</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><span id="cid:6A60D7B0-4538-4BEA-92A0-1045934B89AB@hsd1.co.comcast.net"><Screen Shot 2015-12-08 at 3.54.37 PM.png></span></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;">Where heavy performance is not required, for-in is more readable, maintainable, and optimizable to a sufficient extent that I do not see it as a bar to conversion.</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;">-- E</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class="">On Dec 11, 2015, at 8:44 AM, Paul Cantrell via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;">Your revised results are now right in line with what I get in my test harness, so that’s reassuring!</div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;">I’d quibble with this:</div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;"><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><ol class="MailOutline"><li class="">The optimized builds are still slower than the for-in “equivalent” functionality.</li></ol></div></div></blockquote><br class=""></div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;">That’s not an accurate summary. Depending on precisely what’s in the loop, the for-in flavor is clocking in anywhere from 80% slower to 20%<span class="Apple-converted-space"> </span><i class="">faster</i>.</div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;">None of this performance testing undercuts your entirely valid concerns about syntax. We have, I think, widespread agreement on the list that the C-style for is very rarely used in most Swift code in the wild — but if your usage patterns are unusual and you use it a lot, I can see why you’d be reluctant to part with it!</div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;">It’s a question, then, of whether it’s worth having a leaner language at the expense of making some less-common code more verbose when optimized. I’m not sure that any of the C-style audits people have done on the list have been games. Are there other game developers on the list using Swift who could do the audit on their code?</div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;">Cheers,</div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;">Paul</div><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;"><div class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;"><blockquote type="cite" class=""><div class="">On Dec 11, 2015, at 2:33 AM, David Owens II <<a href="mailto:david@owensd.io" class="">david@owensd.io</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">I don’t know what you did, your gist 404s. </div><div class=""><br class=""></div><div class="">Here’s an update with the while-loop: <a href="https://gist.github.com/owensd/b438bea90075907fa6ec" class="">https://gist.github.com/owensd/b438bea90075907fa6ec</a> and using both i and j within the loops. This is a simple OS X framework project with unit tests.</div><div class=""><br class=""></div><div class=""><b class="">Debug Build:</b></div><div class=""><ul class="MailOutline"><li class="">testZipStride - 2.496s</li><li class="">testCStyleFor - 0.210s</li><li class="">testWhileLoop - 0.220s</li></ul><div class=""><div class=""><b class=""><br class=""></b></div><div class=""><b class="">Release Build:</b></div><div class=""><ul class="MailOutline"><li class="">testZipStride - 0.029s</li><li class="">testCStyleFor - 0.018s</li><li class="">testWhileLoop - 0.019s</li></ul><div class=""><br class=""></div></div></div></div><div class="">I ran these tests from my MacBook Pro, the previous tests were from my iMac.</div><div class=""><br class=""></div><div class="">When you use the sum += (i - j) construct, I think all you are ending up with a hot-path that the optimizer can end up optimizing better (my guess is that the i-j turns into a constant expression - after all, the difference is always 1, but I don’t know enough about the SIL representation to confirm that). If you use a code path where that expression is not constant time (again, assuming my suspicion is correct), the zip+stride is against slower.</div><div class=""><br class=""></div><div class="">I would argue the following:</div><div class=""><br class=""></div><div class=""><ol class="MailOutline"><li class="">The code is not objectively easier to read or understand with the zip+stride construct (arguably, they are not even semantically equivalent).</li><li class="">The debug builds are prohibitively slower, especially in the context of high-performance requirement code (I’m doing a lot of prototyping Swift in the context of games, so yes, performance matters considerably).</li><li class="">The optimized builds are still slower than the for-in “equivalent" functionality.</li><li class="">The optimizer is inconsistent, like all optimizers are (this is a simple truth, not a value judgement - optimizers are not magic, they are code that is run like any other code and can only do as well as they are coded under the conditions they are coded against), at actually producing similar results with code that ends up with slightly different shapes.</li><li class="">There is not functionally equivalent version of the code that I can write that is not more verbose, while requiring artificial scoping constructs, to achieve the same behavior.</li></ol></div><div class=""><br class=""></div><div class="">So no, there is no evidence that I’ve seen to reconsider my opinion that this proposal should not be implemented. If there is evidence to show that my findings are incorrect or a poor summary of the general problem I am seeing, then of course I would reconsider my opinion.</div><div class=""><br class=""></div><div class="">-David</div><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 10, 2015, at 9:12 PM, Paul Cantrell <<a href="mailto:cantrell@pobox.com" class="">cantrell@pobox.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">Hold the presses.</div><div class=""><br class=""></div><div class="">David, I found the radical differences in our results troubling, so I did some digging. It turns out that the zip+stride code:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;"> <span class="" style="color: rgb(50, 62, 125);">var</span><span class="Apple-converted-space"> </span>sum =<span class="Apple-converted-space"> </span><span class="" style="color: rgb(50, 62, 125);">0</span></div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="color: rgb(50, 62, 125);">for</span><span class="Apple-converted-space"> </span>(i, j)<span class="Apple-converted-space"> </span><span class="" style="color: rgb(50, 62, 125);">in</span><span class="Apple-converted-space"> </span><span class="" style="color: rgb(88, 126, 168);">zip</span>(<span class="" style="color: rgb(88, 126, 168);">first</span>.<span class="" style="color: rgb(88, 126, 168);">stride</span>(to:<span class="Apple-converted-space"> </span><span class="" style="color: rgb(50, 62, 125);">0</span>, by: -<span class="" style="color: rgb(50, 62, 125);">1</span>),<span class="Apple-converted-space"> </span><span class="" style="color: rgb(88, 126, 168);">second</span>.<span class="" style="color: rgb(88, 126, 168);">stride</span>(to:<span class="Apple-converted-space"> </span><span class="" style="color: rgb(50, 62, 125);">0</span>, by: -<span class="" style="color: rgb(50, 62, 125);">2</span>)) <span class="" style="font-size: 10.5px;">{</span></div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="color: rgb(50, 62, 125);">if</span><span class="Apple-converted-space"> </span>i %<span class="Apple-converted-space"> </span><span class="" style="color: rgb(50, 62, 125);">2</span><span class="Apple-converted-space"> </span>==<span class="Apple-converted-space"> </span><span class="" style="color: rgb(50, 62, 125);">0</span><span class="Apple-converted-space"> </span>{<span class="Apple-converted-space"> </span><span class="" style="color: rgb(50, 62, 125);">continue</span><span class="Apple-converted-space"> </span>}</div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;"> sum +=<span class="Apple-converted-space"> </span><span class="" style="color: rgb(50, 62, 125);">1</span></div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;"> }</div></div><div class=""><br class=""></div><div class="">…runs<span class="Apple-converted-space"> </span><i class="">much</i><span class="Apple-converted-space"> </span>faster if you actually use both i and j inside the loop:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;"> <span class="" style="color: rgb(50, 62, 125);">var</span><span class="Apple-converted-space"> </span>sum =<span class="Apple-converted-space"> </span><span class="" style="color: rgb(50, 62, 125);">0</span></div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="color: rgb(50, 62, 125);">for</span><span class="Apple-converted-space"> </span>(i, j)<span class="Apple-converted-space"> </span><span class="" style="color: rgb(50, 62, 125);">in</span><span class="Apple-converted-space"> </span><span class="" style="color: rgb(88, 126, 168);">zip</span>(<span class="" style="color: rgb(88, 126, 168);">first</span>.<span class="" style="color: rgb(88, 126, 168);">stride</span>(to:<span class="Apple-converted-space"> </span><span class="" style="color: rgb(50, 62, 125);">0</span>, by: -<span class="" style="color: rgb(50, 62, 125);">1</span>),<span class="Apple-converted-space"> </span><span class="" style="color: rgb(88, 126, 168);">second</span>.<span class="" style="color: rgb(88, 126, 168);">stride</span>(to:<span class="Apple-converted-space"> </span><span class="" style="color: rgb(50, 62, 125);">0</span>, by: -<span class="" style="color: rgb(50, 62, 125);">2</span>)) {</div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;"><span class="" style="font-size: 10.5px;"> </span><span class="" style="font-size: 10.5px; color: rgb(50, 62, 125);">if</span><span class="" style="font-size: 10.5px;"><span class="Apple-converted-space"> </span>i %<span class="Apple-converted-space"> </span></span><span class="" style="font-size: 10.5px; color: rgb(50, 62, 125);">2</span><span class="" style="font-size: 10.5px;"><span class="Apple-converted-space"> </span>==<span class="Apple-converted-space"> </span></span><span class="" style="font-size: 10.5px; color: rgb(50, 62, 125);">0</span><span class="" style="font-size: 10.5px;"><span class="Apple-converted-space"> </span>{<span class="Apple-converted-space"> </span></span><span class="" style="font-size: 10.5px; color: rgb(50, 62, 125);">continue</span><span class="" style="font-size: 10.5px;"><span class="Apple-converted-space"> </span>}</span></div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;"> sum +=<span class="Apple-converted-space"> </span><b class="">i-j</b></div><div class="" style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;"> }</div></div><div class=""><br class=""></div><div class="">Weird, right? This is with optimization on (default “production” build). It smells like a compiler quirk.</div><div class=""><br class=""></div><div class="">With that tweak, the zip+stride approach actually clocks in faster than the C-style for. Yes, you read that right:<span class="Apple-converted-space"> </span><i class="">faster</i>. Also smells like a quirk. Am I doing something fantastically stupid in my code? Or maybe it’s just my idiosyncratic taste in indentation? :P</div><div class=""><br class=""></div><div class="">Here’s my test case, which was a command-line app with manual timing, followed by David’s dropped into the same harness, followed by David’s but with sum += i-j instead of sum += 1:</div><div class=""><div class=""><br class=""></div><div class=""> <a href="https://gist.github.com/pcantrell/6bbe80e630d227ed0262" class="">https://gist.github.com/pcantrell/6bbe80e630d227ed0262</a></div></div><div class=""><br class=""></div><div class="">Point is:<span class="Apple-converted-space"> </span><b class="">no big performance difference here; even a performance advantage</b><span class="Apple-converted-space"> </span>(that is probably a compiler artifact).</div><div class=""><br class=""></div><div class="">David and Thorsten, you might want to reconsider your reviews?</div><div class=""><br class=""></div><div class="">Results:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">—————— Paul’s comparison ——————</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">zip+stride</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 0: 0.519110977649689</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 1: 0.503385007381439</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 2: 0.503321051597595</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 3: 0.485216021537781</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 4: 0.524757027626038</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 5: 0.478078007698059</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 6: 0.503880977630615</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 7: 0.498068988323212</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 8: 0.485781013965607</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> ——————————————</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Median: 0.524757027626038</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">C-style</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 0: 0.85480797290802</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 1: 0.879491031169891</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 2: 0.851797997951508</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 3: 0.836017966270447</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 4: 0.863684952259064</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 5: 0.837742984294891</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 6: 0.839070022106171</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 7: 0.849772989749908</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 8: 0.819278955459595</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> ——————————————</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Median: 0.863684952259064</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">Zip+stride takes 0.607579217692143x the time of C-style for</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">—————— David’s comparison ——————</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">zip+stride</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 0: 1.15285503864288</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 1: 1.1244450211525</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 2: 1.24192994832993</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 3: 1.02782195806503</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 4: 1.13640999794006</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 5: 1.15879601240158</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 6: 1.12114900350571</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 7: 1.21364599466324</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 8: 1.10698300600052</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> ——————————————</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Median: 1.13640999794006</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">C-style</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 0: 0.375869989395142</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 1: 0.371365010738373</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 2: 0.356527984142303</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 3: 0.384984970092773</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 4: 0.367590010166168</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 5: 0.365644037723541</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 6: 0.384257972240448</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 7: 0.379297018051147</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 8: 0.363133013248444</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> ——————————————</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Median: 0.367590010166168</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">Zip+stride takes 3.09151491202482x the time of C-style for</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">—————— David’s comparison, actually using indices in the loop ——————</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">zip+stride</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 0: 0.328687965869904</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 1: 0.332105994224548</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 2: 0.336817979812622</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 3: 0.321089029312134</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 4: 0.338591992855072</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 5: 0.348567008972168</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 6: 0.34687602519989</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 7: 0.34755402803421</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 8: 0.341500997543335</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> ——————————————</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Median: 0.338591992855072</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">C-style</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 0: 0.422354996204376</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 1: 0.427953958511353</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 2: 0.403640985488892</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 3: 0.415378987789154</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 4: 0.403639018535614</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 5: 0.416707038879395</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 6: 0.415345013141632</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 7: 0.417587995529175</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Iter 8: 0.415713012218475</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> ——————————————</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> Median: 0.403639018535614</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">Zip+stride takes 0.838848518865867x the time of C-style for</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">Program ended with exit code: 0</div></div><div class=""><br class=""></div><div class="">Cheers,</div><div class=""><br class=""></div><div class="">Paul</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class="">On Dec 10, 2015, at 5:36 PM, David Owens II <<a href="mailto:david@owensd.io" class="">david@owensd.io</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">Here’s my basic test case:</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><font face="Menlo" class="">let first = 10000000</font></div><div class=""><font face="Menlo" class="">let second = 20000000</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">class LoopPerfTests: XCTestCase {</font></div><div class=""><font face="Menlo" class=""> </font></div><div class=""><font face="Menlo" class=""> func testZipStride() {</font></div><div class=""><span class="" style="font-family: Menlo;"> </span><span class="" style="font-family: Menlo;">self</span><span class="" style="font-family: Menlo;">.</span><span class="" style="font-family: Menlo;">measureBlock</span><span class="" style="font-family: Menlo;"> {</span></div><div class=""><font face="Menlo" class=""> var sum = 0</font></div><div class=""><font face="Menlo" class=""> for (i, j) in zip(first.stride(to: 0, by: -1), second.stride(to: 0, by: -2)) {</font></div><div class=""><font face="Menlo" class=""> if i % 2 == 0 { continue }</font></div><div class=""><font face="Menlo" class=""> sum += 1</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class=""> print(sum)</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class=""> </font></div><div class=""><font face="Menlo" class=""> func testCStyleFor() {</font></div><div class=""><font face="Menlo" class=""> self.measureBlock {</font></div><div class=""><font face="Menlo" class=""> var sum = 0</font></div><div class=""><font face="Menlo" class=""> for var i = first, j = second; i > 0 && j > 0; i -= 1, j -= 2 {</font></div><div class=""><font face="Menlo" class=""> if i % 2 == 0 { continue }</font></div><div class=""><font face="Menlo" class=""> sum += 1</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class=""> print(sum)</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">}</font></div></blockquote><div class=""><br class=""></div><div class="">Non-optimized timings:</div><div class=""><ul class=""><li class="">testCStyleFor - 0.126s</li><li class="">testZipStride - 2.189s</li></ul></div><div class=""><br class=""></div><div class="">Optimized timings:</div><div class=""><div class=""><ul class=""><li class="">testCStyleFor - 0.008s</li><li class="">testZipStride - 0.015s</li></ul></div></div><div class=""><br class=""></div><div class="">That’s a lot worse than 34%; even in optimized builds, that’s 2x slower and in debug builds, that’s 17x slower. I think it’s unreasonable to force people to write a more verbose while-loop construct to simply get the performance they need.</div><div class=""><br class=""></div><div class="">Also, the readability argument is very subjective; for example, I don’t find the zip version more readability. In fact, I think it obscures what the logic of the loop is doing. But again, that’s subjective.</div><div class=""><br class=""></div><div class="">-David</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class="">On Dec 10, 2015, at 2:41 PM, Paul Cantrell <<a href="mailto:cantrell@pobox.com" class="">cantrell@pobox.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class="">Is there any guarantee that these two loops have the exact same runtime performance?</div><div class=""><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><font face="Menlo" class="">for (i, j) in zip(10.stride(to: 0, by: -1), 20.stride(to: 0, by: -2)) {</font></div><div class=""><font face="Menlo" class=""> if i % 2 == 0 { continue }</font></div><div class=""><font face="Menlo" class=""> print(i, j)</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">for var i = 10, j = 20; i > 0 && j > 0; i -= 1, j -= 2 {</font></div><div class=""><font face="Menlo" class=""> if i % 2 == 0 { continue }</font></div><span class="" style="font-family: Menlo;"> print(i, j)</span><div class=""><font face="Menlo" class="">}</font></div></blockquote><div class=""><blockquote type="cite" class=""></blockquote><blockquote type="cite" class=""></blockquote></div></div></div></div></blockquote></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;">In a quick and dirty test, the second is approximately 34% slower.</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;">I’d say that’s more than acceptable for the readability gain. If you’re in that rare stretch of critical code where the extra 34% actually matters, write it using a while loop instead.</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;">P</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><blockquote type="cite" class=""><div class="">On Dec 10, 2015, at 4:07 PM, David Owens II via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 10, 2015, at 1:57 PM, thorsten--- via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><span class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px; float: none; display: inline !important;">Yes, performance is one thing neglected by the discussions and the proposal.</span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"></div></blockquote></div><br class=""><div class="">This is my primary objection to to this proposal; it assumes (or neglects?) that all of the types used can magically be inlined to nothing but the imperative code. This isn’t magical, someone has to implement the optimizations to do this.</div><div class=""><br class=""></div><div class="">Is there any guarantee that these two loops have the exact same runtime performance?</div><div class=""><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><font face="Menlo" class="">for (i, j) in zip(10.stride(to: 0, by: -1), 20.stride(to: 0, by: -2)) {</font></div><div class=""><font face="Menlo" class=""> if i % 2 == 0 { continue }</font></div><div class=""><font face="Menlo" class=""> print(i, j)</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">for var i = 10, j = 20; i > 0 && j > 0; i -= 1, j -= 2 {</font></div><div class=""><font face="Menlo" class=""> if i % 2 == 0 { continue }</font></div><span class="" style="font-family: Menlo;"> print(i, j)</span><div class=""><font face="Menlo" class="">}</font></div></blockquote><div class=""><blockquote type="cite" class=""></blockquote><blockquote type="cite" class=""></blockquote></div><div class=""><br class=""></div><div class="">And can you guarantee that performance is relatively the same across debug and release builds? Because historically, Swift has suffered greatly in this regard with respects to the performance of optimized versus non-optimized builds.</div></div><div class=""><br class=""></div><div class="">These types of optimizer issues are real-world things I’ve had to deal with (and have written up many blog posts about). I get the desire to simplify the constructs, but we need an escape hatch to write performant code when the optimizer isn’t up to the job.</div><div class=""><br class=""></div><div class="">-David</div><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=zCg-2FSGF9Wk188a6c55kLyEbrj7YhaXxFEHM-2F-2B0YAlzVbqZGAg4i3SBvgPUw5uEFQbr8fEPwqqUFQb7VZ4tlBpU-2FZ9Wdcv90oH0fJ5jP-2Bd-2BnfAB5xQ-2FM8ILhQ3CMsUuyVyp8wO2XudWrUmtfVjPbV7-2FcRr-2F8nfR2mO0llGnjqSoJp9kM8-2FYGDP5kOXzyQ-2FlA6CTMKS3GoaGJ19o1vTnpVZE3I-2B2L-2FHgQNqIkOBllOTIE-3D" alt="" width="1" height="1" border="0" class="" style="height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;"></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div></div></blockquote></div><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;"><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=r5jpKsi6nat7oa43lpCLi5GRGm2utDkbDscuFklXZ2e-2FSkRt7e6I1o2MAl9NLe825VfQvgPZ-2Bgwi1WhH3Zn7DZXtvtBdUj4-2BchGiz1pe8vcl08SwziTG69YdVQnCNouERvUiArp6u18zgKOtQi55WMArYuoxMozcgzicjiy-2FrttK-2BkIv1-2FDU9c68YAEiJwTtoOoHQPD6Qlmo-2BZWjlGGPmiiroehJuD1L7tqHfn8w9Fw-3D" alt="" width="1" height="1" border="0" class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px; height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;"><span class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px; float: none; display: inline !important;"><span class="Apple-converted-space"> </span></span><span class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px; float: none; display: inline !important;">_______________________________________________</span><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;"><span class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px; float: none; display: inline !important;">swift-evolution mailing list</span><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;"><a href="mailto:swift-evolution@swift.org" class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;">swift-evolution@swift.org</a><br class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="" style="font-family: Palatino-Roman; font-size: 14px; font-style: normal; font-variant: 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-stroke-width: 0px;">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=pngPxwQ4BiP5IDU2rQC6TcjbiXVR4eqjpuzmzac21kgWOS8ddZk4dkzW9cPKHuJ9eYBJliWnt9kmW4XDvhL0wchQ4ySgt1GJqIJZ0xDEM8m-2B-2FtIOicNUs7i-2FecQ-2FAXDoAAO9aerMpdP30QiOkwOpnu4eBFApadjCFJiDLVJ5KkFyQDR1UJRDuQgkxswVRBaeabuEiubQamcIpPnB-2Fi2MZTfqrcsumGvHOxjGJd98gU8-3D" alt="" width="1" height="1" border="0" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px; height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px; float: none; display: inline !important;" class=""><span class="Apple-converted-space"> </span>_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px; float: none; display: inline !important;" class="">swift-evolution mailing list</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;" class=""><a href="mailto:swift-evolution@swift.org" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;" class="">swift-evolution@swift.org</a><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br class=""></body></html>