Are there any benefits to using a custom existential over `Any`?

as an implementation detail, are there any benefits to defining a custom protocol, and storing existentials of that protocol over just storing values of type Any? in my case, there are no API considerations here, this is purely an implementation concern.

If P is a class-constrained protocol, a value of type P will take up less space than a value of type Any. But if you can accept the class constraint, and you don't need the actual protocol, you could also just use AnyObject.

If P is not a class-constrained protocol, a value of type P will take up more space than a value of type Any, and I can't think of any reason that would be reliably better. Obviously, you can get mysterious benefits from e.g. things falling on different cache lines, but that's not something you can reasonably anticipate.

1 Like

for some reason, the REPL is showing the protocol existential as taking up 40B of storage, as opposed to 32B for the Any value:

Welcome to Swift version 5.6-dev (LLVM 88b7f320545fe57, Swift 6e11611bc811cb8).
Type :help for assistance.
  1> MemoryLayout<Any>.stride
$R0: Int = 32
  2> protocol Foo {}
  3> MemoryLayout<Foo>.stride 
$R1: Int = 40

Sorry, there was a copy-and-paste error; I edited my reply.

1 Like

Foo in this case is Any + Foo's witness table.

Does the compiler every optimize this, in cases where all conformances of a P belong to classes, and not structs or enums?

We don’t currently, no.