[swift-evolution] [Review] SE-0007 Remove C-style for-loops with conditions and incrementers

thorsten at portableinnovations.de thorsten at portableinnovations.de
Fri Dec 11 01:47:27 CST 2015


Big thanks for doing the measurements!

-Thorsten 

> Am 11.12.2015 um 00:36 schrieb David Owens II <david at owensd.io>:
> 
> Here’s my basic test case:
> 
> let first = 10000000
> let second = 20000000
> 
> class LoopPerfTests: XCTestCase {
>     
>     func testZipStride() {
>         self.measureBlock {
>             var sum = 0
>             for (i, j) in zip(first.stride(to: 0, by: -1), second.stride(to: 0, by: -2)) {
>                 if i % 2 == 0 { continue }
>                 sum += 1
>             }
>             print(sum)
>         }
>     }
>     
>     func testCStyleFor() {
>         self.measureBlock {
>             var sum = 0
>             for var i = first, j = second; i > 0 && j > 0; i -= 1, j -= 2 {
>                 if i % 2 == 0 { continue }
>                 sum += 1
>             }
>             print(sum)
>         }
> 
>     }
> 
> }
> 
> Non-optimized timings:
> testCStyleFor - 0.126s
> testZipStride - 2.189s
> 
> Optimized timings:
> testCStyleFor - 0.008s
> testZipStride - 0.015s
> 
> 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.
> 
> 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.
> 
> -David
> 
>>> On Dec 10, 2015, at 2:41 PM, Paul Cantrell <cantrell at pobox.com> wrote:
>>> 
>>> Is there any guarantee that these two loops have the exact same runtime performance?
>>> 
>>> for (i, j) in zip(10.stride(to: 0, by: -1), 20.stride(to: 0, by: -2)) {
>>>    if i % 2 == 0 { continue }
>>>    print(i, j)
>>> }
>>> 
>>> for var i = 10, j = 20; i > 0 && j > 0; i -= 1, j -= 2 {
>>>    if i % 2 == 0 { continue }
>>>    print(i, j)
>>> }
>> 
>> 
>> In a quick and dirty test, the second is approximately 34% slower.
>> 
>> 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.
>> 
>> P
>> 
>> 
>> 
>>>> On Dec 10, 2015, at 4:07 PM, David Owens II via swift-evolution <swift-evolution at swift.org> wrote:
>>>> 
>>>> 
>>>> On Dec 10, 2015, at 1:57 PM, thorsten--- via swift-evolution <swift-evolution at swift.org> wrote:
>>>> 
>>>> Yes, performance is one thing neglected by the discussions and the proposal.
>>> 
>>> 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.
>>> 
>>> Is there any guarantee that these two loops have the exact same runtime performance?
>>> 
>>> for (i, j) in zip(10.stride(to: 0, by: -1), 20.stride(to: 0, by: -2)) {
>>>    if i % 2 == 0 { continue }
>>>    print(i, j)
>>> }
>>> 
>>> for var i = 10, j = 20; i > 0 && j > 0; i -= 1, j -= 2 {
>>>    if i % 2 == 0 { continue }
>>>    print(i, j)
>>> }
>>> 
>>> 
>>> 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.
>>> 
>>> 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.
>>> 
>>> -David
>>> 
>>> _______________________________________________
>>> 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/20151211/da209b06/attachment-0001.html>


More information about the swift-evolution mailing list