Fix random tests
[folly.git] / folly / test / RandomTest.cpp
1 /*
2  * Copyright 2014 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "folly/Random.h"
18 #include "folly/Range.h"
19 #include "folly/Benchmark.h"
20 #include "folly/Foreach.h"
21
22 #include <glog/logging.h>
23 #include <gtest/gtest.h>
24
25 #include <algorithm>
26 #include <thread>
27 #include <vector>
28 #include <random>
29
30 using namespace folly;
31
32 TEST(Random, Simple) {
33   uint32_t prev = 0, seed = 0;
34   for (int i = 0; i < 1024; ++i) {
35     EXPECT_NE(seed = randomNumberSeed(), prev);
36     prev = seed;
37   }
38 }
39
40 TEST(Random, MultiThreaded) {
41   const int n = 1024;
42   std::vector<uint32_t> seeds(n);
43   std::vector<std::thread> threads;
44   for (int i = 0; i < n; ++i) {
45     threads.push_back(std::thread([i, &seeds] {
46       seeds[i] = randomNumberSeed();
47     }));
48   }
49   for (auto& t : threads) {
50     t.join();
51   }
52   std::sort(seeds.begin(), seeds.end());
53   for (int i = 0; i < n-1; ++i) {
54     EXPECT_LT(seeds[i], seeds[i+1]);
55   }
56 }
57
58 BENCHMARK(minstdrand, n) {
59   BenchmarkSuspender braces;
60   std::random_device rd;
61   std::minstd_rand rng(rd());
62
63   braces.dismiss();
64
65   FOR_EACH_RANGE (i, 0, n) {
66     doNotOptimizeAway(rng());
67   }
68 }
69
70 BENCHMARK(mt19937, n) {
71   BenchmarkSuspender braces;
72   std::random_device rd;
73   std::mt19937 rng(rd());
74
75   braces.dismiss();
76
77   FOR_EACH_RANGE (i, 0, n) {
78     doNotOptimizeAway(rng());
79   }
80 }
81
82 BENCHMARK(threadprng, n) {
83   BenchmarkSuspender braces;
84   ThreadLocalPRNG tprng;
85   tprng();
86
87   braces.dismiss();
88
89   FOR_EACH_RANGE (i, 0, n) {
90     doNotOptimizeAway(tprng());
91   }
92 }
93
94 BENCHMARK(RandomDouble) { doNotOptimizeAway(Random::randDouble01()); }
95 BENCHMARK(Random32) { doNotOptimizeAway(Random::rand32()); }
96 BENCHMARK(Random32Num) { doNotOptimizeAway(Random::rand32(100)); }
97 BENCHMARK(Random64) { doNotOptimizeAway(Random::rand64()); }
98 BENCHMARK(Random64Num) { doNotOptimizeAway(Random::rand64(100ul << 32)); }
99 BENCHMARK(Random64OneIn) { doNotOptimizeAway(Random::oneIn(100)); }
100
101 int main(int argc, char** argv) {
102   testing::InitGoogleTest(&argc, argv);
103   google::ParseCommandLineFlags(&argc, &argv, true);
104
105   if (FLAGS_benchmark) {
106     folly::runBenchmarks();
107   }
108   return RUN_ALL_TESTS();
109 }