Unlock This Episode
Our Free plan includes 1 subscriber-only episode of your choice, plus weekly updates from our newsletter.
Last week we explored performance in the Composable Architecture. We looked at the tools it comes with that help you troubleshoot and improve application performance, and we also fixed some longstanding performance problems that existed in the library itself.
But we’re still not quite done making performance improvements, because just after we recorded and edited that episode we found yet another opportunity to eke out more performance. There’s another part of the library that isn’t as efficient as it could be, and that’s in a dependency that the library heavily leans on to earn the “composable” in its name: and that’s Case Paths.
Case paths are a topic we introduced more than a year and a half ago when we theorized what key paths would like look for enums. Swift’s key paths are a wonderful feature that allow you to write algorithms over the shape of a struct by isolating a single field from the rest. Our case paths do the same, except they isolate a single case from the rest of an enum.
We were even able to make case paths as ergonomic as key paths. Just as the compiler generates a key path for each field of a struct automatically, we were able to automatically generate a case path for each case of an enum by making use of Swift’s reflection APIs. We even introduced a prefix operator so that the actual syntax looks similar to key paths.
In those episodes we stressed that reflection can be difficult to get write since you are operating outside the purview of the compiler, but even worse, it can also be quite slow. Using reflection APIs creates a lot of unnecessary objects, and unfortunately this penalty shows up in case paths.
The series of episodes in which Case Paths were first theorized and introduced.
Key paths are an incredibly powerful feature of the Swift language: they are compiler-generated bundles of getter-setter pairs and are automatically made available for every struct property. So what happens when we theorize an equivalent feature for every enum case?
A post on the official Swift Blog explaining how Swift’s reflection APIs work, including calls to functions that live on the runtime metadata, like the enum tag code we use in this week’s episode.
A series of posts on the Swift runtime.
A complete reflection library for Swift.