What is the cost of any vs some on a hot path?
Mental model. A witness call is looking up the phone number every time you want to say hello. A specialized call already has them on speed dial.
any: the value may be boxed on the heap, every method call is indirect through a witness table, the caller cannot inline, and the existential container itself is larger than the payload.
some / generics: the concrete type is known, so after specialization the call is direct or inlined, and the value can stay in registers.
In a body, a scroll handler, a per-frame loop, or a JSON parser, prefer some or concrete types. At a module boundary called once per user action, any is usually fine.
Common traps
- Micro-optimizing a path that runs ten times per session. Measure before you restructure an API around dispatch cost.
- Forgetting the allocation, not just the call. Boxing a large struct into an existential can dominate the cost.
- Assuming
any Viewis “just a bit slower”. In SwiftUI it defeats view identity, which changes behaviour, not only speed.
They might follow up with
- How would you measure? Instruments Time Profiler plus a signpost around the hot loop; look for
swift_dynamicCastand witness thunks. - Can a generic be faster than a concrete call? After specialization it usually becomes the same machine code.
Related questions
- 1.4.2 some View vs any View — what is the difference, and why does SwiftUI use some?
- 1.4.6 What is an existential container? What is a witness table?
- 1.4.1 Generics vs protocols as types: when do you write <T: P>(T) vs any P?
← some View vs any View — what is the difference, and why does SwiftUI… What is the difference between some P as a parameter (Swift 5.7) and… →