Logo 61e73bc61c0e1780102320e879dc3cac0e29303ea8894dd8f10c942f3ba8120f

otters.io

An adorable little blog

Craig Said It Would Be Fast

Friday — June 27th, 2014

Swift has been declassified for long enough to do some playing around and this slide is still etched into my mind from the WWDC 2014 keynote.


Swift speed slide

Apple made some pretty big claims on Swift's performance. While Objective-C isn't the fastest baseline in the world it's no slouch. Stating that Swift could be faster certainly grabbed my attention. Getting Objective-C levels of performance with a friendlier syntax is one tantalizing offer.


No doubt, being able to control a language from top to bottom and not letting people scribble all over memory will likely make the neighborhood safer. This controlled environment could allow for some compiler optimizations that something more open to low level tinkering, such as C, would not.


The operations Federighi compared on stage were a tad cherry-picked but impressive nonetheless. Sorting and RC4 are fine and well for comparison but I want to see more. I want to compare actual code. So let's look at a simple for loop. Converting this common Objective-C snippet to Swift is trivial.


Objective-C

Time taken: 0.002209 seconds

double start = CFAbsoluteTimeGetCurrent();

for (int i = 0; i <= 1000000; i++);

double timeTaken = CFAbsoluteTimeGetCurrent() - start;

NSLog(@"Time taken: %f seconds", timeTaken);

Swift

Time taken: 0.667608 seconds

let start = CFAbsoluteTimeGetCurrent()

for i in (0...1000000) {}

let timeTaken = CFAbsoluteTimeGetCurrent() - start

println("Time taken: \(timeTaken) seconds")



Here we're doing a ridiculous number of iterations to make the difference noticeable. Upon comparing the time of the two snippets, Objective-C is faster to the tune of 300x. Why? Because the Swift code is asking the program to do just a bit more than its Objective-C counterpart. The Swift snippet is actually creating a range from 0 to 1,000,000 before it ever begins iterating. Changing the Swift snippet to use a classic C-style for loop speeds things up considerably.


Swift With C-Style For Loops

Time taken: 0.024894 seconds

let start = CFAbsoluteTimeGetCurrent()

for (var i = 0; i <= 1000000; i++) {}

let timeTaken = CFAbsoluteTimeGetCurrent() - start

println("Time taken: \(timeTaken) seconds")



After this minor change, the Swift snippet is still 10x slower than the original Objective-C version but certainly closer. It's worth noting that in both cases XCode's LLVM code generation optimizations have been turned off and both snippets are being run on the same little Mac mini.


This comparison is just one of many, but the general result of my time with Swift is that it can be faster than Objective-C in some cases. In others it could be slower. Though most of this is irrelevant for my workflow. I make simple apps that work with fairly small datasets and avoid implementing crypto when someone else has done the work.


With Swift, I find myself spending less time thinking about how I'm going to accomplish what I set out to do and more time thinking about what I'm going to do. This sort of freedom from the machine is what drew me to the likes of Ruby. After spending time with Swift it is difficult to use Objective-C without thinking how easy it would be to just do the project at hand in Swift.


For me, and a large number of people with similar needs, the big speed boost in Swift isn't going to happen at runtime. It's going to be at dev time. Not just the milliseconds shaved off by no longer needing to type square brackets but rather the fact that I don't have to think in terms of alloc init. Swift is a welcome and well-needed abstraction in my book.