Performance of generic protocol extension (30x slower, Swift 4.2)

Generics are fast when the compiler can specialize them, but suffer from speed issues when the compiler cannot see what it needs in order to specialize them and thus has to pass around protocol witness tables instead.

There are two things which could be unnecessarily preventing the compiler from specializing your methods:

  1. If the protocol is in a separate module from the type that conforms to it, then when the type is compiled, it does not have access to the implementation to specialize it and has to call it generically. Fix this by adding @inlinable to the protocol extension methods to make their implementations visible to other modules. (@inlinable has repercussions for module stability, but I doubt those apply here.) You can read about it in the attribute list of The Swift Programming Language and find more detail in its evolution proposal.
  2. If the protocol is in the same module but a separate file from the type that conforms to it, make sure that whole module optimization has not been disabled. Here is an older blog post about it.
2 Likes