random.SystemRandom().randint() inefficient

Chris Angelico rosuav at gmail.com
Tue Jul 26 19:43:20 EDT 2022


On Wed, 27 Jul 2022 at 09:28, Dennis Lee Bieber <wlfraed at ix.netcom.com> wrote:
>
> On Tue, 26 Jul 2022 16:38:38 +0200, Cecil Westerhof <Cecil at decebal.nl>
> declaimed the following:
>
> >I need to get a random integer. At first I tried it with:
> >    from secrets import randbelow
> >    index = randbelow(len(to_try))
> >
> >This works perfectly, but it took some time. So I thought I try:
> >    from random  import SystemRandom
> >    index = SystemRandom().randint(0, len(to_try) - 1)
> >
> >A first indication is that the second version would take about two
> >times as much time as the first. Is there a reason for this, or should
> >this not be happening?
>
>         Well, off the top of my head...
>
>         For one generation of "index" you are first creating an instance of
> SystemRandom(), using it to generate your random integer, and then
> disposing of the instance.
>
>         If you only need ONE random integer, the time difference probably
> doesn't matter. OTOH, if you need many during the run, using
>
>         sr = SystemRandom()
>         #stuff in some loop that generates multiple ints
>                 index = sr.randint(...)
>
>         Hmmm, wonder if there is a speed difference between
>                 .randint(0, len(to_try) - 1)
> and
>                 .randint(1, len(to_try)) - 1
>

Probably not significant, since the same amount of arithmetic gets
done either way. But switching to single-arg randrange(len(to_try))
will definitely help, and IMO is clearer as well (since the
implication is selecting one from a group of items).

Incidentally - if you are actually trying to select a specific item,
you may want to consider random.choice.

ChrisA


More information about the Python-list mailing list