<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></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 Mar 8, 2016, at 11:38, Dmitri Gribenko 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="">On Sun, Mar 6, 2016 at 6:16 PM, Kevin Ballard via swift-evolution<br class=""><<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><blockquote type="cite" class="">On Sun, Mar 6, 2016, at 05:46 AM, Patrick Pijnappel wrote:<br class=""><br class="">My intuition says the extra state & branch needed for generators like<br class="">TakeWhile could very well be optimized away in most cases if you dont make<br class="">use of its post-nil behavior. Say TakeWhile is implemented as such:<br class=""><br class="">if done { return nil }<br class="">guard let element = base.next() where predicate(element) else {<br class=""> done = true<br class=""> return nil<br class="">}<br class="">return element<br class=""><br class="">If the generator is then used in the common case:<br class=""><br class="">let generator = TakeWhileGenerator(...)<br class="">while let element = generator.next() {<br class=""> foo(element)<br class="">}<br class=""><br class="">Should give us effectively:<br class=""><br class="">var base = ...<br class="">let predicate = ...<br class="">var done = false<br class="">while true {<br class=""> if done { break }<br class=""> guard let element = base.next() where predicate(element) else {<br class=""> done = true<br class=""> break<br class=""> }<br class=""> foo(element)<br class="">}<br class=""><br class="">The optimizer should see (or at least could see) `done` is never read after<br class="">it's written to (thus removing the assignment), and therefore when checking<br class="">the condition it can only be false (thus it can also be removed).<br class=""><br class=""><br class="">This may be doable for stdlib generators, but Swift currently has a<br class="">limitation where generic types/functions defined outside the current file<br class="">(or module with -whole-module-optimization) are only specialized for their<br class="">parameters if they come from the stdlib. Any such types/functions defined in<br class="">third-party libraries (or in other files if you're not using<br class="">-whole-module-optimization) use virtual dispatch on the generic parameters<br class="">instead. This means that any generic GeneratorTypes defined in third-party<br class="">libraries won't be able to optimize away this check as it won't be able to<br class="">tell that it isn't needed.<br class=""></blockquote><br class="">This is a current limitation of the compiler. The resilience effort<br class="">should make the specialization available for user-defined modules.<br class="">Thus, I don't think it makes sense to factor in the current limitation<br class="">into a long-term decision.</div></div></blockquote><br class=""></div><div>That's not really true; in fact I'd say it's the opposite. Any library that's not shipped with the app has the freedom to change its generator implementation in the future, and therefore you'll get <i class="">even fewer</i> guarantees about the generator than you have today.</div><div><br class=""></div><div>Jordan</div><br class=""></body></html>