Monday, February 2, 2015

Swift Resistance

David Owens II (Open Radar):

The fundamental problem with Swift, with regards to performance, is that it is impossible to reason what the performance of your code is going to be. It is impossible to know if your code is just horrendously slow in debug, or if the optimizing is going to get ride of all of the extra crap that is going on.


If most of your code is Swift code that is simply bridging into ObjC or C, you will probably read this post and not have a clue what I’m talking about. You are benefiting from the speed of ObjC.

Profiling showed that a lot of the slowness was from ARC adding unnecessary retains and releases that are only removed when doing an optimized build. Debugging is harder with optimization on, however, and the Swift compiler doesn’t let you selectively disable optimization for a file you are trying to debug.

David Owens II:

Now, had this performance been like 300% slower, I might have been able to take that and the safety justifications… maybe. At least if it was only 300% slower I’d still be in a spot where I could run my game at 30Hz with reasonable head room left over for other logic to run.

But no… we are talking about this loop taking 1 entire SECOND to compute. It was nearly 28,000% slower…


OK, so let’s be explicitly clear here: this post is not about how Swift is horrendously slow in builds you’ll be giving your customers. No, it’s about how terribly slow and painful your life as a developer will be trying to write any amount of Swift code that works on any reasonable amount of data inside of arrays in Swift. However, you can see that none of the Swift options are faster or even as fast as the C version. And frankly, none of them are really that much clearer… but that’s a different topic.

Joseph Lord:

Where I would dispute with David is his view that this is an absolute showstopper than cripple’s Swift’s usefulness. There are ways to manage without the debugger, it still works with the assembly if needed anyway and as I illustrate there are workarounds for the issue.

However in the repo I show the workaround of moving performance critical code to a library or framework that can be built optimised while the bulk of the complexity and logic in the project is run without optimisation for simplicity of debugging.

David Owens II:

The other problem with this statement (and the solution presented) is that it assumes that we can optimize the slow parts of the game by putting the code into a framework. Ok… besides the annoying mess that is to pull stuff in and out of there, and completely ignoring that this is a trivial example of one algorithm that would need to be moved, it completely misses the fact that it’s that very slow part that I need to debug because something strange is going on. If my debug build is now running at 2 or 3 Hz, it becomes extremely difficult (impossible really) to actually play to game to get the error that is to be debugged.


I do take back what I said yesterday somewhat, to the extent that:

(Apple bug 1) not only do per-file flags seem to be completely ignored altogether on Swift source files (I tried with -toto, it did not appear in the command line while building), contrary to what I implied yesterday,

(Apple bug 2) but also Swift code does not appear to be supported at the moment in static library targets (it failed when I tried and I found reports that appear to confirm this),

(Apple bug 3) and framework targets containing Swift code do not play well with command line tool targets,

I am forced to reach the conclusion that, since you can’t reasonably put it in a separate area where it can be optimized differently (and be accessed by command-line targets, which is essential for specifically testing that code instead of having to do it through an app), Swift is unsuitable for multimedia code at the time being (Mac OS X Yosemite and Xcode 6.1.1, if you’re an Apple engineer reading…). Period.

2 Comments RSS · Twitter

What I didn't mention is that sometimes it's not even possible to use your optimized build because of optimizer bugs. They are getting fixed, but we haven't seen a new drop for Swift in a while.

I would agree with David's comment on this about optimizer bugs. That is a real worry at the moment and a bigger worry for me than the debug performance (although I admit it does make that more important).

Does anyone have a good list of known issues, I think I may have hit one with implicitly unwrapped optionals (returned by an Apple API I don't use them myself) but can't reproduce it under test.

Leave a Comment