Swift v1.2 β2 Performance

I've been taking a look at performance of Swift for a while now, with two very specific focus points:

  1. Developer workflow (non-optimized builds)
  2. Real-time applications (fully-optimized builds)

I'm very happy to report that Swift v1.2 β2 seems to have made some really great improvements in performance, even over Swift v1.2 β1.

Performance Numbers1

Language: C, Optimization: -O0                    ┃  6.3 β2  ┃  6.3 β1  ┃  6.1.1   ┃
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━┩
RenderGradient (Pointer Math)                     │   38.651 │   38.266 │   38.780 │
──────────────────────────────────────────────────┴──────────┴──────────┴──────────┘

Language: C, Optimization: -Os                    ┃  6.3 β2  ┃  6.3 β1  ┃  6.1.1   ┃
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━┩
RenderGradient (Pointer Math)                     │   10.374 │   10.042 │   10.162 │
──────────────────────────────────────────────────┴──────────┴──────────┴──────────┘

Language: C, Optimization: -Ofast                 ┃  6.3 β2  ┃  6.3 β1  ┃  6.1.1   ┃
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━┩
RenderGradient (Pointer Math)                     │    3.112 │    3.022 │    2.976 │
──────────────────────────────────────────────────┴──────────┴──────────┴──────────┘

Language: Swift, Optimization: -Onone             ┃  6.3 β2  ┃  6.3 β1  ┃  6.1.1   ┃
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━┩
RenderGradient ([Pixel])                          │ 3684.914 │ 4012.283 │ 29134.32 │
RenderGradient (UnsafeMutablePointer)             │ 171.3359 │ 162.9272 │ 152.2643 │
RenderGradient ([Pixel].withUnsafeMutablePointer) │ 386.9801 │ 523.7199 │ 1159.273 │
──────────────────────────────────────────────────┴──────────┴──────────┴──────────┘

Language: Swift, Optimization: -O                 ┃  6.3 β2  ┃  6.3 β1  ┃  6.1.1   ┃
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━┩
RenderGradient ([Pixel])                          │ 26.91437 │ 46.57198 │ 66.40995 │
RenderGradient (UnsafeMutablePointer)             │ 22.71384 │ 21.74668 │ 22.21477 │
RenderGradient ([Pixel].withUnsafeMutablePointer) │ 22.33094 │ 39.78517 │ 39.62590 │
──────────────────────────────────────────────────┴──────────┴──────────┴──────────┘

Language: Swift, Optimization: -Ounchecked        ┃  6.3 β2  ┃  6.3 β1  ┃  6.1.1   ┃
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━┩
RenderGradient ([Pixel])                          │ 19.66853 │ 40.28331 │ 66.04476 │
RenderGradient (UnsafeMutablePointer)             │ 20.02236 │ 19.53774 │ 19.51404 │
RenderGradient ([Pixel].withUnsafeMutablePointer) │ 20.25013 │ 41.26989 │ 38.34509 │
──────────────────────────────────────────────────┴──────────┴──────────┴──────────┘

This is great! The worst case, [Pixel], in non-optimized builds was 29s back in Xcode 6.1.1 (the latest official build). In latest beta, that's down to 3.6s! Sure, that's still a horribly slow time, but that's still a massive improvement.

The other thing to note is that nearly all of the optimized builds got twice as fast as before. The biggest thing to note here is that the usage of arrays is now just as good in optimized builds as the pointer versions. That's a big win for code clarity. Once the debug performance of arrays is fully addressed, this will be even better.

Hopefully 6.3 β3 shows just as remarkable improvements.

Also, I've started a GitHub repo to start tracking this stuff better:

https://github.com/owensd/swift-perf.

Feel free to send any pull requests for items you'd like to see tracked here. I do plan on doing some updates to the infrastructure piece of it to get some easier delta reporting.

  1. The times should be read as: "the amount of time, in milliseconds, it took to compute 30 iterations".
Swift v1.2 β2 Performance