Swift’s Native Clocks Are Very Inefficient
In a nutshell, the problem is that Swift’s
Clock
protocol has significant overheads by design. If you look at a time profile of code like this, you’ll see things like[…]That’s a lot of time wasted in function calls and struct initialisation and type conversion and protocol witnesses and all that guff. The only part that’s actually retrieving the time is the
swift_get_time
call (which is just a wrapper overclock_gettime
, which is just a wrapper overclock_gettime_nsec_np(CLOCK_UPTIME_RAW)
, which is just a wrapper overmach_absolute_time
).[…]
The downside to calling
mach_absolute_time
directly, though, is that it’s on Apple’s “naughty” list – apparently it’s been abused for device fingerprinting, so Apple require you to beg for special permission if you want to use it (even though it’s used by all these other APIs anyway, as the basis for their implementations, and there’s nothing you can get frommach_absolute_time
that you can’t get from them too 🤨).
This matches my experience that intuition is often wrong regarding Swift performance. Sometimes what seems like it would be a simple virtual call has more overhead than an Objective-C message send. Various dynamic stuff involving checking types/protocols can also be much slower than with Objective-C. The good news is that Date
is fast, not even calling down to NSDate
, and that there’s a pull request to inline some of this.
Previously:
1 Comment RSS · Twitter · Mastodon
I agree on the Swift performance thing. We’re at a point now where I consider anything Swift to be slow, until proven otherwise. When the Swift team released their embedded version for Playdate it came the claim that it was performant. So I asked for some figures: of course there were none. It was just an assumption on their part: it’s Swift, so it must be performant. I measured the performance and it ran at 60% of the speed of the C version it was a port of. Embarrassing.