[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