This kind of bounds check are normally not ever violated (in well formed code) so branch prediction predicts them correctly nearly always.
It also is (normally) just jumping in the bad case, which means with a correct branch predictions thy can be really cheap.
And then cpu "magic" tends to be optimized for that kind of checks at they appear in a lot of languages (e.g. Java).
Then in many cases the compiler can eliminate the checks partially.
For example any many kinds of for-each element iterations the compiler can infer that the result of the conditionally loop continuation check implies the bounds check. Combine that with loop unrolling which can reduce the number of continuation checks and you might end up with even less.
Also bounds checks tend to be an emergency guard, so you tend to sometimes do checks yourself before indexing and the compiler can often use that to eliminate the bounds check.
And even if you ignore all optimizations it's (assuming in bounds) "just" at most one int/pointer cmp (cheap) followed by a conditional branch which doesn't branch (cheap).