Skip to content

Instantly share code, notes, and snippets.

@jirassimok
Last active October 12, 2019 02:02
Show Gist options
  • Save jirassimok/47bfc1a1821212487e81447dee9b9ee3 to your computer and use it in GitHub Desktop.
Save jirassimok/47bfc1a1821212487e81447dee9b9ee3 to your computer and use it in GitHub Desktop.
Test Python's random number generation time in edge cases for StackOverflow
#!/user/bin/env python3
# Code written while writing this StackOverflow answer:
# https://stackoverflow.com/a/58126026
from timeit import timeit
def test(bit_lengths, trials=10000, unit=1000, rounding=16):
"""Test how long it takes to find a random n-bit number less than the largest
and smallest number with exactly that many bits.
See https://stackoverflow.com/a/58126026 for details.
bit_lengths = iterable of bit-lengths to test
trials = number of runs for the highest and lowest number of each bit length
unit = times will be shown in (1/unit) seconds (e.g. 1000 for milliseconds)
rounding = how many digits to show
"""
scale = unit
r = rounding
col1 = max(len('bits'), len(str(max(bit_lengths)))) # length of 1st header
sep = ' '
h1 = f'{"2 ** (n - 1)":<{r+2}}'
if len(h1) > r + 2:
h1 = f'{"low":<{r+2}}'
h2 = f'{"(2 ** n) - 1":<{r+2}}'
if len(h2) > r + 2:
h2 = f'{"high":<{r+2}}'
print(f'{"bits":>{col1}}', h1, h2, 'ratio', sep=sep)
for n in bit_lengths:
low = 2 ** (n - 1)
high = 2 ** n - 1
lowtime = timeit(f'randrange({low})',
setup='from random import randrange',
number=trials) * scale / trials
hightime = timeit(f'randrange({high})',
setup='from random import randrange',
number=trials) * scale / trials
low = f'{lowtime:.{r}f}'.rstrip('0')
high = f'{hightime:.{r}f}'.rstrip('0')
ratio = f'{lowtime / hightime :.{r}f}'.rstrip('0')
print(f'{n:>{col1}}',
f'{low: <{r+2}}',
f'{high: <{r+2}}',
f'{ratio:<{r+2}}', sep=sep)
if __name__ == '__main__':
test([2 ** n for n in range(6, 12)],
trials=1_000_000,
unit=1_000_000, # microseconds
rounding=10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment