Having type annotations is a big deal because you can infer certain things at compile time.
Take for instance (+ x y). In CLisp "+" is a multi-method, the dispatch being done at runtime, but if you know that x and y are both integers, there's no need to search the right method to call at runtime, its address is already known. And then you can also decide to inline its code at compile-time if there aren't any conflicts (mostly like a macro, but without the laziness).
Of course, in dynamically-typed languages you have the freedom to infer these things at runtime, in certain situations you can infer the types of "x" and "y", you can use a cache for the call sites, and so on, but it's a lot more complicated, and one of the reasons is that for every optimization you do, you have to be ready to de-optimize when the assumptions have been invalidated.
That's why I said SBCL doesn't count as being dynamic in that test because it probably makes full use of those static annotations.
Having type annotations is a big deal because you can infer certain things at compile time.
Take for instance (+ x y). In CLisp "+" is a multi-method, the dispatch being done at runtime, but if you know that x and y are both integers, there's no need to search the right method to call at runtime, its address is already known. And then you can also decide to inline its code at compile-time if there aren't any conflicts (mostly like a macro, but without the laziness).
Of course, in dynamically-typed languages you have the freedom to infer these things at runtime, in certain situations you can infer the types of "x" and "y", you can use a cache for the call sites, and so on, but it's a lot more complicated, and one of the reasons is that for every optimization you do, you have to be ready to de-optimize when the assumptions have been invalidated.
That's why I said SBCL doesn't count as being dynamic in that test because it probably makes full use of those static annotations.