Skip to content

Instantly share code, notes, and snippets.

@kaixiong
Last active December 20, 2015 02:38
Show Gist options
  • Save kaixiong/6057346 to your computer and use it in GitHub Desktop.
Save kaixiong/6057346 to your computer and use it in GitHub Desktop.
Benchmarks of various ways to generate random numbers in a given range
#include <cstdint>
#include <ctime>
#include <random>
#include <boost/format.hpp>
#define RUN_COUNT 100000
#define RANGE_MIN 100
#define RANGE_MAX 100000
typedef std::minstd_rand PRNG;
namespace {
inline uint64_t timestamp ()
{
timespec time;
clock_gettime (CLOCK_MONOTONIC, &time);
return time.tv_sec * uint64_t (1000000000) + time.tv_nsec;
}
}
int main (int argc, char** argv)
{
PRNG prng;
std::vector<uint32_t> array {RUN_COUNT};
array.resize (RUN_COUNT);
// #1: Modulo
auto start_time = timestamp ();
for (unsigned int i = 0; i < RUN_COUNT; i++) {
array[i] = prng () % (RANGE_MAX - RANGE_MIN + 1) + RANGE_MIN;
}
auto time1 = timestamp () - start_time;
// #2: Scaling with integer multiplication and division
start_time = timestamp ();
for (unsigned int i = 0; i < RUN_COUNT; i++) {
array[i] = (prng () * (RANGE_MAX - RANGE_MIN)) / (prng.max () - prng.min ()) + RANGE_MIN;
}
auto time2 = timestamp () - start_time;
// #3: Scaling with floating-point multiplication and division
start_time = timestamp ();
for (unsigned int i = 0; i < RUN_COUNT; i++) {
array[i] = float (prng ()) / (prng.max () - prng.min ()) * (RANGE_MAX - RANGE_MIN) + RANGE_MIN;
}
auto time3 = timestamp () - start_time;
// #4: C++11's std::uniform_int_distribution
start_time = timestamp ();
for (unsigned int i = 0; i < RUN_COUNT; i++) {
std::uniform_int_distribution<uint32_t> distrib{RANGE_MIN, RANGE_MAX};
array[i] = distrib (prng);
}
auto time4 = timestamp () - start_time;
// #5: C++11's std::uniform_int_distribution (reused)
start_time = timestamp ();
std::uniform_int_distribution<uint32_t> distrib{RANGE_MIN, RANGE_MAX};
for (unsigned int i = 0; i < RUN_COUNT; i++) {
array[i] = distrib (prng);
}
auto time5 = timestamp () - start_time;
// Display timings for comparison
std::cout << boost::format {"Method 1: %.8f (%+.4f%%)\n"} % (double (time1) / 1000000000.0) % (double (time1) / time1 * 100.0 - 100.0);
std::cout << boost::format {"Method 2: %.8f (%+.4f%%)\n"} % (double (time2) / 1000000000.0) % (double (time2) / time1 * 100.0 - 100.0);
std::cout << boost::format {"Method 3: %.8f (%+.4f%%)\n"} % (double (time3) / 1000000000.0) % (double (time3) / time1 * 100.0 - 100.0);
std::cout << boost::format {"Method 4: %.8f (%+.4f%%)\n"} % (double (time4) / 1000000000.0) % (double (time4) / time1 * 100.0 - 100.0);
std::cout << boost::format {"Method 5: %.8f (%+.4f%%)\n"} % (double (time5) / 1000000000.0) % (double (time5) / time1 * 100.0 - 100.0);
return EXIT_SUCCESS;
}
/*
g++ -O2 -g -Wall -pedantic -std=c++11 random.cpp -o random -lr
Results:
kaixiong@kaixiong-zenbook:~/Documents/projects/expt$ ./random
Method 1: 0.00222034 (+0.0000%)
Method 2: 0.00218799 (-1.4567%)
Method 3: 0.00221519 (-0.2318%)
Method 4: 0.00922058 (+315.2783%)
Method 5: 0.00278417 (+25.3938%)
kaixiong@kaixiong-zenbook:~/Documents/projects/expt$ ./random
Method 1: 0.00226707 (+0.0000%)
Method 2: 0.00213056 (-6.0214%)
Method 3: 0.00223113 (-1.5853%)
Method 4: 0.00489745 (+116.0251%)
Method 5: 0.00284279 (+25.3945%)
kaixiong@kaixiong-zenbook:~/Documents/projects/expt$ ./random
Method 1: 0.00227261 (+0.0000%)
Method 2: 0.00214656 (-5.5465%)
Method 3: 0.00220350 (-3.0407%)
Method 4: 0.00698950 (+207.5542%)
Method 5: 0.00282391 (+24.2587%)
kaixiong@kaixiong-zenbook:~/Documents/projects/expt$ ./random
Method 1: 0.00227164 (+0.0000%)
Method 2: 0.00215942 (-4.9398%)
Method 3: 0.00214239 (-5.6896%)
Method 4: 0.00779363 (+243.0841%)
Method 5: 0.00276684 (+21.7992%)
kaixiong@kaixiong-zenbook:~/Documents/projects/expt$ ./random
Method 1: 0.00222016 (+0.0000%)
Method 2: 0.00217719 (-1.9351%)
Method 3: 0.00223086 (+0.4821%)
Method 4: 0.00912261 (+310.8992%)
Method 5: 0.00275899 (+24.2701%)
kaixiong@kaixiong-zenbook:~/Documents/projects/expt$ ./random
Method 1: 0.00221965 (+0.0000%)
Method 2: 0.00216394 (-2.5101%)
Method 3: 0.00220133 (-0.8252%)
Method 4: 0.00622905 (+180.6318%)
Method 5: 0.00283261 (+27.6150%)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment