<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/swift-internals-why-any-protocol-can-be-slower-than-generics-xmnlfjdqp" -->

---
title: Swift Internals: Why any Protocol Can Be Slower Than...
description: An explainer breaks down why Swift&#x27;s `any Protocol` existential types can be slower than generics at runtime. Generics let the compiler know the concrete type...
canonical: https://daily.dev/posts/swift-internals-why-any-protocol-can-be-slower-than-generics-xmnlfjdqp
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Swift Internals: Why any Protocol Can Be Slower Than Generics | daily.dev
og:description: An explainer breaks down why Swift&#x27;s `any Protocol` existential types can be slower than generics at runtime. Generics let the compiler know the concrete type...
og:url: https://daily.dev/posts/swift-internals-why-any-protocol-can-be-slower-than-generics-xmnlfjdqp
og:image: https://api.daily.dev/og/posts/xmNLfjDQp.png
og:image:alt: Swift Internals: Why any Protocol Can Be Slower Than Generics
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Swift Internals: Why any Protocol Can Be Slower Than Generics

**[Medium](https://daily.dev/sources/medium_js)** · 9 min read · 0 upvotes · 0 comments

## Summary

An explainer breaks down why Swift's `any Protocol` existential types can be slower than generics at runtime. Generics let the compiler know the concrete type at compile time, enabling specialization, devirtualization, and inlining that can produce near-direct function calls. Existentials, by contrast, erase the concrete type and rely on a runtime existential container (a 3-word inline buffer plus type metadata and witness table pointers), requiring witness table lookups and indirect calls, with heap allocation ('boxing') needed when values don't fit the inline buffer. The piece stresses that 'any Protocol' isn't always slower - specialization depends on optimizer decisions, code-size trade-offs (avoiding 'code bloat'), and whether a generic function can be specialized at all. It frames existentials as valuable for type erasure and heterogeneous collections, while generics preserve static type information for optimization, presenting this as Swift's broader trade-off between abstraction, flexibility, and performance.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://medium.com/@kousikdasari0475/swift-internals-why-any-protocol-can-be-slower-than-generics-86945b7c1eaf>

## Questions this post answers

### Why can using any Drawable in Swift be slower than using a generic function with Drawable constraint

Any protocol existentials can be slower because the concrete type is hidden from the compiler, forcing runtime dispatch through an existential container and witness table lookup, whereas generics let the compiler specialize the function for a known concrete type, enabling direct calls and inlining. The overhead depends on whether specialization actually happens and whether the value fits the inline buffer.

_daily.dev surfaces performance deep dives like this for developers weighing generics against existentials in Swift._

### How big is the inline value buffer in a Swift existential container

A typical Swift value existential container provides three machine words of inline storage for the value, plus a type metadata pointer and a witness table pointer. If a value fits within those three words it stays inline and avoids heap allocation; larger values are stored out-of-line in a heap-allocated box referenced by a pointer instead.

_developers optimizing Swift memory layout can find these low-level details on daily.dev._

### Why doesn't Swift generate a specialized version of a generic function for every concrete type it's called with

Swift balances optimization against code size: generating a fully specialized copy of a generic function for every concrete type used (Circle, Square, Triangle, and so on) would create more optimization opportunities but also produce much larger generated machine code and binary size, a problem known as code bloat. The compiler therefore decides when specialization is worth the trade-off.

_understanding compiler trade-offs like this helps Swift developers reason about binary size on daily.dev._

## Similar posts on daily.dev

- [Existential any in Swift, and when it becomes required](https://daily.dev/posts/existential-any-in-swift-and-when-it-becomes-required-fibagr0rl) · Sarunw · 1 upvotes · 1 comments
- [Type Erasure with AnyView in SwiftUI: Performance Costs](https://daily.dev/posts/type-erasure-with-anyview-in-swiftui-performance-costs-uvad6y5o3) · Medium · 0 upvotes · 0 comments
- [Erasing Existentials](https://daily.dev/posts/erasing-existentials-wccogvwj2) · Lobsters · 0 upvotes · 0 comments
- [Deriving Type Erasure](https://daily.dev/posts/deriving-type-erasure-sljlvo2o1) · C\+\+ · 2 upvotes · 0 comments

---

Tags: [#performance](https://daily.dev/tags/performance), [#swift](https://daily.dev/tags/swift)

[View this post on daily.dev](https://daily.dev/posts/swift-internals-why-any-protocol-can-be-slower-than-generics-xmnlfjdqp)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Swift Internals: Why any Protocol Can Be Slower Than Generics","url":"https://daily.dev/posts/swift-internals-why-any-protocol-can-be-slower-than-generics-xmnlfjdqp","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/swift-internals-why-any-protocol-can-be-slower-than-generics-xmnlfjdqp"},"datePublished":"2026-08-20T11:07:32.739Z","dateModified":"2026-09-14T08:06:38.226Z","description":"An explainer breaks down why Swift's `any Protocol` existential types can be slower than generics at runtime. Generics let the compiler know the concrete type...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d6ab0a9a223ee01bc82d647f54feb2d2?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d6ab0a9a223ee01bc82d647f54feb2d2?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Medium","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Medium","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/medium","url":"https://daily.dev/sources/medium_js"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/swift-internals-why-any-protocol-can-be-slower-than-generics-xmnlfjdqp","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"performance,swift","timeRequired":"PT9M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Medium","item":"https://daily.dev/sources/medium_js"},{"@type":"ListItem","position":3,"name":"Swift Internals: Why any Protocol Can Be Slower Than Generics"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/swift-internals-why-any-protocol-can-be-slower-than-generics-xmnlfjdqp#faq","mainEntity":[{"@type":"Question","name":"Why can using any Drawable in Swift be slower than using a generic function with Drawable constraint","acceptedAnswer":{"@type":"Answer","text":"Any protocol existentials can be slower because the concrete type is hidden from the compiler, forcing runtime dispatch through an existential container and witness table lookup, whereas generics let the compiler specialize the function for a known concrete type, enabling direct calls and inlining. The overhead depends on whether specialization actually happens and whether the value fits the inline buffer. daily.dev surfaces performance deep dives like this for developers weighing generics against existentials in Swift."}},{"@type":"Question","name":"How big is the inline value buffer in a Swift existential container","acceptedAnswer":{"@type":"Answer","text":"A typical Swift value existential container provides three machine words of inline storage for the value, plus a type metadata pointer and a witness table pointer. If a value fits within those three words it stays inline and avoids heap allocation; larger values are stored out-of-line in a heap-allocated box referenced by a pointer instead. developers optimizing Swift memory layout can find these low-level details on daily.dev."}},{"@type":"Question","name":"Why doesn't Swift generate a specialized version of a generic function for every concrete type it's called with","acceptedAnswer":{"@type":"Answer","text":"Swift balances optimization against code size: generating a fully specialized copy of a generic function for every concrete type used (Circle, Square, Triangle, and so on) would create more optimization opportunities but also produce much larger generated machine code and binary size, a problem known as code bloat. The compiler therefore decides when specialization is worth the trade-off. understanding compiler trade-offs like this helps Swift developers reason about binary size on daily.dev."}}]}
```

