AFAIK typed racket does type-checking during compilation (via raco); the resulting code is no slower than normal Racket, although I'm not sure if it's faster either.
The contract system is different; it works on normal, untyped Racket code and performs checks at runtime; similar to using Python decorators to check the input and output of a function. This slows things down, so it's recommended to only check things at module boundaries. For example:
#lang racket
(require racket/contract)
(require racket/match)
(provide factorial)
(define/contract (factorial n)
(-> exact-nonnegative-integer?
exact-nonnegative-integer?)
(fact n))
(define (fact n)
(match n
[0 1]
[_ (* n (fact (- n 1)))]))
This module exposes the `factorial` function, which checks (at runtime) whether its argument and return value are non-negative integers (i.e. 0, 1, 2, ...). The actual calculation is done by the `fact` function, which is private and doesn't do any checks. If we don't separate the checks from the calculation, we would end up running the checks on every recursive call, which would slow things down a lot.As far as I'm aware, Racket's gradual typing is done by contracts at the interface between typed and untyped code. Hence it's not that typed racket is slow, it's that passing untyped values into typed functions can be slow, if we want accurate blame information for errors.