The really expensive part here is not the use of a protocol, it’s the downcast (which isn’t really idiomatic Swift). Static dispatch is always faster than dynamic dispatch/polymorphism, but protocols are usually reasonably efficient (even more so if you can use generics instead of existentials).