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/rand
library 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
math
allows 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/v2
orencoding/json/v2
. - Go1 requires compatibility guarantees, making it impractical to directly modify the original library. The issues with
math/rand
are also more prominent and evident.
change list
- Removed
Rand.Read
and the top-levelRead
function. - Removed
Source.Seed
,Rand.Seed
, and the top-levelSeed
function (meaning that top-level functions likeInt
will always use random seeding). - Removed
Source64
, asSource
now provides theUint64
method, making the original methods unnecessary. - Utilized a more direct implementation for
Float32
andFloat64
. For example, in the case ofFloat64
, the original implementation usedfloat64(r.Int63()) / (1<<63)
. However, this had a problem of occasionally rounding to1.0
, whileFloat64
should never round. The improvement involves changing it tofloat64(r.Int63n(1<<53)) / (1<<53)
, which avoids the rounding issue. - Implemented
Rand.Perm
usingRand.Shuffle
. This improves efficiency and ensures only one implementation. - Renamed
Int31
,Int31n
,Int63
, andInt64n
toInt32
,Int32n
,Int64
, andInt64n
, respectively. These names were unnecessary and confusing. - Added
Uint32
,Uint32n
,Uint64
,Uint64n
,Uint
, andUintn
as 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
Source
called 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:
int
int8
int16
int32
int64
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