[swift-evolution] [Pitch] Retiring `where` from for-in loops

Erica Sadun erica at ericasadun.com
Thu Jun 9 11:00:23 CDT 2016


Missed pasting this one bit:

var value = 0
func doSomething() {
    // some numeric load
    value += 1
}


> On Jun 9, 2016, at 9:59 AM, Erica Sadun via swift-evolution <swift-evolution at swift.org> wrote:
> 
> My results:
> 
> -Onone (None)
> 
> plain for loop with guard
> Elapsed time: 0.0563530325889587
> plain for loop with if
> Elapsed time: 0.0631130337715149
> where test
> Elapsed time: 0.0661619901657104
> eager filter test
> Elapsed time: 0.684610962867737
> lazy filter test
> Elapsed time: 0.640420973300934
> Program ended with exit code: 0
> 
> 
> -O (Fast)
> 
> plain for loop with guard
> Elapsed time: 0.00411999225616455
> plain for loop with if
> Elapsed time: 0.00422400236129761
> where test
> Elapsed time: 0.00419700145721436
> eager filter test
> Elapsed time: 0.033439040184021
> lazy filter test
> Elapsed time: 0.00690501928329468
> Program ended with exit code: 0
> 
> Code:
> 
> public func timetest(_ note: String, block: () -> Void) {
>     let date = NSDate()
>     block()
>     let timeInterval = NSDate().timeIntervalSince(date)
>     print(note); print("Elapsed time: \(timeInterval)")
> }
> 
> let count = 4_000_000
> let range = 1...count
> 
> timetest("plain for loop with guard") {
>     for i in range {
>         guard i % 2 != 0 else { continue }
>         doSomething()
>     }
> }
> 
> timetest("plain for loop with if") {
>     for i in range {
>         if i % 2 == 0 { continue }
>         doSomething()
>     }
> }
> 
> timetest("where test") {
>     for i in range where i % 2 == 0 {
>         doSomething()
>     }
> }
> 
> timetest("eager filter test") {
>     for i in range.filter({ $0 % 2 == 0 }) {
>         doSomething()
>     }
> }
> 
> timetest("lazy filter test") {
>     for i in range.lazy.filter({ $0 % 2 == 0 }) {
>         doSomething()
>     }
> }
> 
> 
>> On Jun 9, 2016, at 4:27 AM, Charlie Monroe <charlie at charliemonroe.net <mailto:charlie at charliemonroe.net>> wrote:
>> 
>>> 
>>> On Jun 9, 2016, at 10:29 AM, Brent Royal-Gordon <brent at architechies.com <mailto:brent at architechies.com>> wrote:
>>> 
>>>> I've taken the time to run a test, going through milion numbers (several times) using:
>>>> 
>>>> for i in arr { if i % 2 == 0 { continue } }
>>>> for i in arr where i % 2 == 0 { }
>>>> for i in arr.filter({ $0 % 2 == 0 }) { }
>>>> for i in arr.lazy.filter({ $0 % 2 == 0 }) { }
>>>> 
>>>> Results:
>>>> 
>>>> - plain for loop with if-continue: 27.19 seconds (+1.76%)
>>>> - with where: 26.72 seconds (+0.00%)
>>>> - .filter: 44.73 seconds (+67.40%)
>>>> - .lazy.filter: 31.66 seconds (+18.48%)
>>> 
>>> This is great data. I have a hard time imagining a little compiler work couldn't make if-continue as fast as for-where, but lazy.filter might be a taller order for it, and optimizing plain filter could actually change behavior.
>>> 
>>> A month or two ago, I actually fell into the "just use the higher-order functions" camp on this question, but I've been rethinking that more and more lately. Between the trailing closure incompatibility, the need to remember to use `lazy` to get decent performance, and now the noticeable speed difference even *with* lazy, I'm no longer convinced that answer is good enough.
>> 
>> There will IMHO always be noticeable overhead since you're calling a function which is then invoking a closure. When you look at what that means:
>> 
>> - thunks generated around the invocation, which are a few instructions
>> - new stack frame for each call (correct me if I'm wrong). 
>> 
>> So instead of a single `i % 2 == 0` (which is just 2-3 instructions, depending on the architecture and optimization settings), it will invoke the closure milion times, if the array contains a milion members.
>> 
>> Maybe I'm over-optimizing, but 18% seemed like a lot to me.
>> 
>> 
>>> 
>>> (Though I do think `while` is probably too niche to bother with as a first-class feature, and I am open to if-continue on the `where` clause.)
>>> 
>>> -- 
>>> Brent Royal-Gordon
>>> Architechies
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160609/bf03ead2/attachment.html>


More information about the swift-evolution mailing list