otp icon indicating copy to clipboard operation
otp copied to clipboard

`rand:bytes` optimization and extended tests

Open RaimoNiskanen opened this issue 4 months ago • 3 comments

Back to my pet peeve, the rand module.

There are tests in rand_SUITE that the base generators follow their reference implementation, but that is really not sufficient. This PR adds tests that the algorithms that limit or expand the numbers to a requested range, creates floating point numbers and shuffles, are not accidentally altered to produce a different sequence.

The PR also adds a new internal plug-in callback function for the algorithm handlers, to generate bytes. This new callback is also used from module crypto to optimize the crypto and crypto_cache algorithms. By this, using the crypto generator in module crypto from rand:bytes is no longer embarrassingly slow since it does not take the detour to generate bytes from integers from bytes.

Also in this PR is a new algorithm in crypto - crypto_prng1, that can create a repeatable sequence with cryptographical unpredictability, as the existing crypto_aes, but with much better performance. This is also because it does not take the unnecessary detour over generating integers, and also uses the new internal plug-in callback for bytes.

And, as usual, the documentation got some attention...

RaimoNiskanen avatar Dec 08 '25 16:12 RaimoNiskanen

CT Test Results

    3 files    100 suites   1h 9m 5s ⏱️ 2 321 tests 2 256 ✅  65 💤 0 ❌ 2 985 runs  2 790 ✅ 195 💤 0 ❌

Results for commit c6ea63e3.

:recycle: This comment has been updated with latest results.

To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass.

See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally.

Artifacts

// Erlang/OTP Github Action Bot

github-actions[bot] avatar Dec 08 '25 16:12 github-actions[bot]

I have not written tests to etch the return values from rand:normal* in stone.

Such tests would be very brittle since a minimal change in the platform's floating point implementation could produce different numbers. Such as the fact that Erlang/OTP has been changed in a recent release to have +0.0 =/= -0.0.

The question is if that is a good decision? Should we draw the border for repeatable sequences at rand:uniform[_real]/0 & rand:uniform[_real]_s/1 (uniform floats) but no further?

I guess this should be documented?

RaimoNiskanen avatar Dec 09 '25 14:12 RaimoNiskanen

Rebased in an attempt to get rid of the SBOM CI error. Minor doc improvements. Squashed an "Update after feedback" commit.

RaimoNiskanen avatar Dec 16 '25 08:12 RaimoNiskanen

Another rebase, not content change

RaimoNiskanen avatar Dec 17 '25 15:12 RaimoNiskanen