New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
new method random.getrandbytes() #57605
Comments
I noticed that several usages of random.getrandbits() actually need bytes. A few examples:
random.getrandbits() itself is not a cheap call: it ends with a call to _PyLong_FromByteArray, and transformation to bytes will involve more copy, conversions from 30bit digits (or 15bit digits) to bytes, or worse. This patch adds random.getrandbytes(), which creates a bytes string directly from calls to genrand_int32(). |
Good idea, IMO. + cum = set() I find this test a bit strange. Also, perhaps it should be bitwise rather than bytewise. |
How would this work for other random number generators that don't supply genrand_int32()? The API for random is supposed to be easily subclassable and reusable for other random number generators. The requirements for those generators is intentionally kept minimal (i.e. they only need to supply random(), seed(), getstate() and setstate() and optionally getrandbits()). I'm -0 on making this API fatter. |
genrand_int32 is an internal function, only available in C for the Mersenne Twister generator. |
Yes, I know. I'm the one added that code ;-)
The problem is that we need an API that will accommodate other random number generators and not be specific to the MersenneTwister. Right now, the starting point for everything in the random module is an underlying generator supplying a random() method returning a float and an optional getrandombits() method which returns an int (possibly a long int). The latter is easily convertible to bytes with to_bytes() which uses a fast O(n) algorithm. ISTM, the getrandbytes() proposal amounts to a micro-optimization of existing capabilities, and it comes at the expense of fattening the API. |
Well, you can provide a default getrandombytes() which calls into
Well, O(n) doesn't necessarily equate fast. Can Amaury post benchmark |
./python -m timeit -s "from random import getrandbits" "getrandbits(8000000).to_bytes(1000000, 'little')" ./python -m timeit -s "from random import getrandbytes" "getrandbytes(1000000)" For the Mersenne Twister, getrandbytes() is ~2.5 times faster (A length of 1000 gives exactly the same ratio) Updated patch to add getrandbytes at the module level, and to SystemRandom. |
The differential cost of generating n random bytes is negligible compared to actually doing anything with the bytes once their generated. This optimization is close to being a total waste (saving 15 milliseconds for the abnormal case of generating 1 million random bytes). |
Closing for the reasons listed above. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: