1

I am drawing random boolean numbers with

std::mt19937 rng;
std::uniform_int_distribution<int> dis(0, 1);

In extreme cases, drawing these numbers can take up to 40% of the CPU time of my process. Is there any way to make this faster?

Remi.b
  • 17,389
  • 28
  • 87
  • 168
  • You can simply make your loop parallel. – TonySalimi Jul 26 '19 at 21:12
  • 2
    How about drawing a number between 0 and 2^64-1, and then using one bit at a time, 64 times in a row, before calculating another random number? – Sam Varshavchik Jul 26 '19 at 21:13
  • 1
    If all you need is a 50/50 random number generator just use `rand`. It's fast and you're not using it for anything cryptographic. – NathanOliver Jul 26 '19 at 21:14
  • @Hoodi The loop was just to express that it will be use many times and because that's how I started to benchmark things. In reality my process cannot be easily parallelized (or rather it already is and can't be further parallelized) – Remi.b Jul 26 '19 at 21:15
  • Without the loop, we lack context. The two remaining lines of code will not take up 40% CPU time by themselves. – JaMiT Jul 27 '19 at 01:33

2 Answers2

6

I would get rid of uniform_int_distribution.

One invocation of std::mt19937::operator() (i.e. doing rng()) will give you 32 random bits, which you can use one by one.

A benchmark shows that this method is about 23 times faster.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • 1
    Can also be applied to different ranges ([as 15](https://stackoverflow.com/a/56979958/2684539)) even if power of 2 seems more natural. – Jarod42 Jul 26 '19 at 21:33
1

You might be happy with @HolyBlackCat answer, but for sampling such values there is a Bernoulli distribution support in C++

Along the lines

std::mt19937 rng{1234567};
std::bernoulli_distribution bd{0.5};

std::cout << bd(rng) << '\n';
std::cout << bd(rng) << '\n';
std::cout << bd(rng) << '\n';
Severin Pappadeux
  • 18,636
  • 3
  • 38
  • 64