Just for a goof, you know. We don’t bend phones for a living.
January 2015 S M T W T F S « Sep 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Just for a goof, you know. We don’t bend phones for a living.
About how swift Apple’s new programming language isn’t.
Update: Hi there! I’m humbled to tell you that, as a few readers have pointed out, the original Swift and Objective-C results in this post were taken from unoptimized builds. We rebuilt the evening of 6/4 with optimizations turned on (-O), and ensured compiler optimization of dead code, ie. assignments being culled because their results aren’t used later, is not a factor (you’d see results orders of magnitude faster, and when we increase the magnitude of our loop count we do see results an order of magnitude slower). We used Swift’s Ints and C’s ints unless otherwise noted. With adjusted numbers in-hand, this post has become something of a living document. Look for new numbers and notes (some stricken!) throughout. -Keith
Swift may be the best thing happening to development on the Mac and iOS right now, with a lot of modern features that’ll help developers new to our platforms and, potentially, make life easier for the older curmudgeons. There’s one thing that’s stuck in my craw since the big reveal yesterday, though: Apple would have you believe Swift is, well, swift. But rewind that keynote video, babe, back to about the 105:00 mark. Stop staring at Craig’s hair. Listen. Really listen. Yep, there’s applause at the initial announcement, but keep listening. Three or four sad claps at the first benchmark comparison and zero at the second.
Why is that?
Because no one in the room bought it?
Being somewhat sensitive to most performance claims myself, I set up a test app in both Swift and Objective-C. Loop a million times, perform a few esoteric bits each time through the loop. Run the code three times, average the elapsed time. Tweak here and there to try to get the best numbers.
Here’s what happened:
Loop a million times
0.0021s (1.7x faster) 0.000021s (29x faster) No work done in the inner loop, just iterate. Swift actually performs pretty well here. It’s a straight C exercise on the Objective-C side, with a conditional assignment in the inner loop to guarantee the compiler didn’t optimize the loop out entirely. Note that in Swift I used a for loop with an index variable incremented with x = x + 1, because ++ is far slower and for _ in 0…999999 is glacial.
0.0023s (10.4x faster) 0.00002s (46x faster) Strangely, Swift has a major performance issue with the ++ operator. It’s roughly 6x s l o w e r than x = x + 1, which is the basic code I used to get the best performance. On the Objective-C side, we placed a conditional assignment in the inner loop to guarantee the compiler didn’t optimize the loop out entirely.
0.0022s (10.9x faster) 0.000021s (31.4x faster)
This is a simple x = y.
Yeowch. I’m guessing Automatic Reference Counting is involved on the Swift side. Retaining and releasing a million times would bring on the hurt. On the Objective-C side, we placed a conditional assignment in the inner loop to guarantee the compiler didn’t optimize the loop out entirely.
Append native string to native array
0.046s (141.1x faster) 0.042 (7.9x faster)
In Swift I used an Array of String. In Objective-C I added an NSString to an NSMutableArray with no optimizations or tweaks. It would be even faster if we dropped to CFMutableArrayRef because in so many cases you don’t need to retain what you add to an array, something NSMutableArray does automatically – and, behind the scenes, Swift is almost surely doing the same because of how Automatic Reference Counting works. Straight C arrays would be blinding. ARC is not a performance optimization.
Append native integer to native array
0.023s (283x faster) 0.023s (13x faster)
In Swift I used an Array of Int. In Objective-C I added an NSNumber to an NSMutableArray with no optimizations or tweaks. It would be even faster if we dropped to CFMutableArrayRef because in so many cases you don’t need to retain what you add to an array, something NSMutableArray does automatically – and, behind the scenes, Swift is almost surely doing the same because of how Automatic Reference Counting works. Straight C arrays would be blinding. ARC is not a performance optimization.
Concatenate two strings
0.27s (21x faster) 0.27s (11.7 faster)
In Swift, the inner loop looked like this:
theString3 = theString + theString2
In Objective-C, the inner loop looked like this:
theString3 = [theString stringByAppendingString:theString2];
What’s the deal?
We can’t know exactly what’s going on behind the scenes, but my hunch is some of what we take for granted in Objective-C – the straight C scalar data types – are actually classes in Swift. And the more you rely on classes, the more Automatic Reference Counting is in there somewhere, retaining and releasing like there’s no tomorrow, often for no good reason.
Coders are constantly balancing trade-offs. Raw performance isn’t always the priority, because you have to conceptualize, code, iterate, debug, extend, refactor, share, ship, maintain, and support. One team’s acceptable trade is another team’s hell stew. For example, we don’t use – surprise! – Automatic Reference Counting at Splasm because, frankly, it’s around 40% slower in some cases, so we’ll leave ARC off and take that 40% back (and we enjoy manual memory management, thank you very much). Other teams wouldn’t give up ARC even if paint dried faster. Did I say ‘if’? Different teams. Different values.
Swift has performance issues in our tests that other teams won’t be concerned about. It’s also a very new language that Apple will improve over time. Though Apple claims big performance gains, we think comparing Swift to Objective-C right now is a little premature. We’ll continue to play with it, learning and sharing with the community, but for the foreseeable future, unless the performance issues evaporate – or Apple abandons Objective-C altogether – we’ll be developing in Objective-C. It has its issues, but well-established design patterns, direct control of memory, more readable (and self-documenting) code, and terrific performance for our users are not among them.
Note that the original results were taken from unoptimized builds. When we rebuilt, Swift became much swifter in some cases and slower, relatively, in others. The closest it came to Objective-C’s performance was a factor of 6.4x slower, and that was in a test we didn’t show results for (appending to an NSMutableArray instead of an Int array in Swift). We’re considering porting a small project over to Swift sooner than later to get a better idea of real world numbers…and we’ll share those when we have them!
The first time you try to print your own return address labels on your Mac, where every printed label has the same name and address, might be the last time. A typical Mac user would think, printing the same thing on every label should “just work”, right? Open Contacts or Address Book, select a contact, go to the File menu to print, hum a little tune, look for an option to print a page of labels instead of a single label, and… But wait. That option isn’t there. Instead, you’ll have to:
It’s not so bad, really, and, unlike many 12-step programs, at least you get consistent results. To be honest, there are general-purpose label apps out there – but they’re a little pricey, and then you’re out $20 or more for something you’d kinda expect to be easier and cheaper. That’s why we made Return Labels. For less than $5, pre-tax, you get an app designed to make return address labels on your Mac, with any combination of font, style, color, or whathaveyou, a beautiful collection of built-in images to choose from (you can drag in your own, too), and an easy way to browse and print your creations later on.
Return Labels. It’s easy. It won’t break the bank. And you get beautiful return address labels, to boot.
Return Labels is the first project for our new guy, William Gill, who joined our team last year. William came with a wealth of programming experience, and took the lead coder position to learn as much as possible about developing Mac apps. Allan Woodall, our lead user support specialist, dug up tons of bugs in the process. Excellent job, William and Allan!
When the Mac App Store opened it came without one key ingredient: an easy way for current users of an app to switch their license to the Mac App Store. App developers like us can give away just 50 free copies for each new version of an app – but that’s nowhere near the number of people out there using CheckBook every day! So what can you do if you originally purchased CheckBook or CheckBook Pro directly from our online store and now you want to move your license to the Mac App Store? Wait for a sale that makes it pretty darn cheap! We hereby proclaim the next three Wednesdays (August 14th, 21st and 28th) will be Mac App Store Amnesty Days. We’ll lower the price of CheckBook Pro to just US $4.99 on these days so you’ll have a chance to move your license over for just 20% of the regular price. And if you originally purchased CheckBook, you’re getting a swell upgrade to CheckBook Pro, to boot! (CheckBook users, check out Moving on up to CheckBook Pro for help getting your CheckBook Accounts into CheckBook Pro).
What are you waiting for? Head to the Mac App Store for your dose of CheckBook Pro amnesty!
If you just got the bug to upgrade from CheckBook to CheckBook Pro, or you’ve moved your license to the Mac App Store (you should – we’re dropping the price on the Mac App Store waaaaay down to $4.99 every Wednesday for the rest of August) you’re in for a treat: CheckBook Pro can read all of your CheckBook data without breaking a sweat. All it needs is a little help to find your CheckBook Accounts document.
If you know where your document’s at, just open it by dragging it onto the CheckBook Pro icon in your Dock or by going to CheckBook’s File menu and clicking the Open… menu item. We’d recommend not keeping the document in your old CheckBook 2 sandbox container (~/Library/Containers/com.splasm.checkbook2/Data/Library/Application Support/Splasm Software, Inc./CheckBook 2) because if you ever remove that container phwooooop! your data will go right along with.
If you’re not sure where your document is, or if it lives in iCloud, open CheckBook, go to the File menu, click the Backup… menu item and save a backup of your Accounts document in your Documents folder. Quit CheckBook, open CheckBook Pro and drag the document backup onto the CheckBook Pro icon in your Dock or go to CheckBook Pro’s File menu and click the Open… menu item. To move the document to iCloud, go to the File menu, click the Move To… menu item and move the document to iCloud from there.
That should do it, but drop us a line at email@example.com if you need a hand. We’re happy to help!
This update resolves a potential data corruption issue in CheckBook 2.5 and 2.5.1 so we strongly recommend you install it as soon as possible. With the help of a small handful of users we found that the issue is so rare that less than 1 out of 250 people would see it – but one user affected by it would be one too many! In addition, we’ve corrected an error that could appear when backing up an Accounts document, and we’ve also thrown in some minor user interface enhancements. To update, go to the CheckBook menu at the top left of your screen and click the Check For Updates… menu item.
CheckBook Pro isn’t affected by the same issue but it’s also been updated to version 2.5.2. To update, go to the CheckBook Pro menu at the top left of your screen and click the Check For Updates… menu item.