You have learned that Objective-C (with its dynamic runtime) in most cases performs more slowly than Swift. Interoperability between Swift and Objective-C is done so seamlessly that sometimes we can use Objective-C types and its runtime in the Swift code without knowing that.
When you use Objective-C types in Swift code, Swift is actually using the Objective-C runtime for method dispatch. Because of that, Swift can't do the same optimization as for pure Swift types. Let's have a look at a simple example:
for _ in 0...100 { _ = NSObject() }
Let's read this code and make some assumptions about how the Swift compiler would optimize that code. The NSObject
instance is never used in the loop body, so we could eliminate creating an object. After that we would have an empty loop that could also be eliminated. So we would remove all the code from execution.
Let's see what is happening in reality by looking at generated assembly pseudocode:
rbx = 0x65; do { rax = [_OBJC_CLASS_...