Go Benchmark
Random Number Generation
math/rand vs math/rand/v2 vs crypto/rand for "I just need a random int".
Every Go developer eventually types "random int" into a search engine and gets three answers: the legacy math/rand, its Go 1.22 successor math/rand/v2, and crypto/rand. This benchmark draws a small random integer with each package. math/rand/v2 replaces the v1 global generator (and its lock contention) with a faster ChaCha8-based per-thread design, while crypto/rand pays for cryptographic security on every draw. The rule of thumb the chart confirms: use math/rand/v2 for everything non-security (v1 is effectively deprecated), and reserve crypto/rand for keys, tokens, and anything an attacker must not predict.
1 CPU
32 CPUs
rand.IntN(100) from math/rand/v2 (Go 1.22+). The global functions use a ChaCha8-based generator with cheap per-thread state instead of a global lock, and the range reduction algorithm avoids v1's modulo bias trick. Faster, safer seeding by default, and the idiomatic choice for all non-cryptographic randomness.
Math Rand #
rand.Intn(100) from the legacy math/rand. The global functions share one generator behind a mutex, so concurrent use contends, and the underlying algorithm is a decades-old additive generator. Kept around for compatibility; new code should not use it.
rand.Int(rand.Reader, max) from crypto/rand, which reads from the operating system's CSPRNG and allocates big.Int values along the way. Orders of magnitude slower — and completely worth it whenever the random value is security-relevant: session tokens, keys, nonces, password salts.
Contributors