The inaugural v2 version of the standard library in Go hails from the esteemed math/rand/v2 repository. It is set to make its grand debut with the official release of Go1.22, poised to serve as a reliable and production-ready resource.
This article is first published in the medium MPP plan. If you are a medium user, please follow me in medium. Thank you very much.
Reasons
- The original
math/randlibrary in the standard package had numerous deficiencies and areas for improvement. These included outdated generators, slow algorithms (performance), and unfortunate conflicts withcrypto/rand.Read, among other issues. - There is a plan in place to upgrade the v2 versions of standard libraries. Starting with
mathallows for the accumulation of experience and resolving tooling ecosystem challenges (such as support from tools like gopls and goimports for v2 packages). Subsequent iterations can then address higher-risk packages, likesync/v2orencoding/json/v2. - Go1 requires compatibility guarantees, making it impractical to directly modify the original library. The issues with
math/randare also more prominent and evident.
change list
- Removed
Rand.Readand the top-levelReadfunction. - Removed
Source.Seed,Rand.Seed, and the top-levelSeedfunction (meaning that top-level functions likeIntwill always use random seeding). - Removed
Source64, asSourcenow provides theUint64method, making the original methods unnecessary. - Utilized a more direct implementation for
Float32andFloat64. For example, in the case ofFloat64, the original implementation usedfloat64(r.Int63()) / (1<<63). However, this had a problem of occasionally rounding to1.0, whileFloat64should never round. The improvement involves changing it tofloat64(r.Int63n(1<<53)) / (1<<53), which avoids the rounding issue. - Implemented
Rand.PermusingRand.Shuffle. This improves efficiency and ensures only one implementation. - Renamed
Int31,Int31n,Int63, andInt64ntoInt32,Int32n,Int64, andInt64n, respectively. These names were unnecessary and confusing. - Added
Uint32,Uint32n,Uint64,Uint64n,Uint, andUintnas top-level functions and methods onRand. - Utilized Lemire’s algorithm in
Intn,Uintn,Int32n,Uint32n,Int64n, andUint64n, resulting in improved performance. - Introduced a new implementation of
Sourcecalled PCG-DXSM, including related APIs likeNewPCG. - Removed the Mitchell & Reeds LFSR generator and
NewSource.
example
Read & Seed
The functions Read and Seed have been removed. It is recommended to use crypto/rand’s Read function instead.
|
|
output:
|
|
For the Seed function, it is advised to call New(NewSource(seed)) in order to reinitialize the random number generator.
internal
The functions N, IntN, and UintN now utilize a novel implementation algorithm. Interested individuals are encouraged to allocate extra time to examine it in detail: A fast alternative to the modulo reduction
The functions Intn, Int31, Int31n, Int63, and Int64n have been renamed as follows: IntN, Int32, Int32N, Int64, and Int64N, respectively.
Additionally, new functions Uint32, Uint32N, Uint64, Uint64N, Uint, and UintN have been introduced to generate random unsigned integers. They have also been added as corresponding functions within the Rand structure.
The newly added function N generates random numbers of arbitrary integer types. This function is implemented using generics, and the following integer types are its type parameters:
intint8int16int32int64
Summary
Today, we have shared and further described the new math/rand/v2 library, highlighting key changes including performance optimization (algorithm rewrite), standardization, and additions of new random generators.
Given the substantial amount of information covered, we have selected and presented only the aspects that are essential for understanding and using the library. However, for those who are interested in delving deeper, it is recommended to refer to the full documentation of https://pkg.go.dev/math/rand/v2@master