💾 Archived View for dioskouroi.xyz › thread › 29419349 captured on 2021-12-05 at 23:47:19. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2021-12-04)

🚧 View Differences

-=-=-=-=-=-=-

The Surprising Cost of Protocol Conformances in Swift

Author: sond813

Score: 58

Comments: 12

Date: 2021-12-02 17:31:17

Web Link

________________________________________________________________________________

earthboundkid wrote at 2021-12-04 05:46:39:

I feels like I must be missing something. 3ms is extremely slow. Surely it should be 3us, no? What’s it doing that is so slow?

sond813 wrote at 2021-12-05 16:52:05:

It’s ms, that slow because every protocol conformance in every dylib needs to be checked. When this gets to 100k+ like in many large apps it takes multiple milliseconds

flohofwoe wrote at 2021-12-04 11:00:46:

Function names like "_dyld_find_protocol_conformance" seem to indicate that DLLs might need to be accessed, and my (entirely subjective) impression is that this general area seems to have become a lot slower in recent macOS versions, at least when system DLLs are involved.

andrekandre wrote at 2021-12-04 00:39:56:

> The concept behind zconform is to eagerly load all possible protocol conformances and store them in a map keyed by the protocol’s address in memory.

if it works well in most scenarios, couldn't this just be implemented directly in the swift runtime at some point?

favorited wrote at 2021-12-04 01:09:00:

Maybe, but Swift is intentionally lazy in lots of ways (globals aren't initialized until the first access, for example).

The trade-off of zconform's approach is that dynamic linking is slowed down by needing to eagerly identify all protocol conformances whenever an image is loaded (including conformances which are never even cast). It does make the performance of dynamic casting more deterministic, but it would slow down (for example) app launch by eagerly pre-caching things which might never be queried.

I'd expect that the response from the Swift team would be to avoid dynamic casting in performance-critical code, rather than pessimize link-time.

[Edit, to clarify why the cache needs to be rebuilt when libraries are loaded]: Swift protocols have a feature called retroactive conformance, which allows apps and libraries to add protocol conformance to types they don't own. So, any library that gets loaded could add a protocol to a type. It's a really powerful feature, but has some unfortunate side-effects...

sond813 wrote at 2021-12-05 19:21:09:

Building up the cache at launch/dynamic link time does have a performance hit of a few ms, but if you know it will save you many runtime checks it can be worth it. Definitely makes sense for the runtime to have the lazy behavior built in. Hopefully the dyld cache will help get the best of both solutions by persisting a cache across multiple launches.

syspec wrote at 2021-12-04 07:26:41:

Swift has a real performance problem, it doesn't seem competitive with other "systems languages"

Is the goal to make it faster later? What can be done to get closer to that goal?

jb1991 wrote at 2021-12-04 08:54:09:

Swift is quite fast as an app programming language. I’ve never understood why anyone could consider it a systems programming language with a straight face. But to say that it has a “real performance problem” is a bit of an exaggeration. Compared to the many other languages out there, it’s faster than most.

syspec wrote at 2021-12-04 12:06:10:

Probably because that is one of the states goals as voiced by the languages creator

jb1991 wrote at 2021-12-05 15:27:57:

That was a long time ago, I thought. The word "systems" was removed from the swift website years ago when it was clear that it did not really have that priority.

syspec wrote at 2021-12-06 03:14:26:

> The goal of the Swift project is to create the best available language for uses ranging from systems programming, to mobile and desktop apps, scaling up to cloud services.

> Fast. Swift is intended as a replacement for C-based languages (C, C++, and Objective-C). As such, Swift must be comparable to those languages in performance for most tasks. Performance must also be predictable and consistent, not just fast in short bursts that require clean-up later. There are lots of languages with novel features — being fast is rare.

Those are literally the stated goals. It does not get more clear than saying "Swift is intended to be a replacement for C-based languages (C, C++)..."

[0]

https://www.swift.org/about/

olliej wrote at 2021-12-04 05:37:21:

This is about the casting cost specifically, not the direct cost of using a protocol as interface, which itself has some annoying performance characteristics