Adjusts pass counts for maps
[folly.git] / folly / stress-test / stress-sequential-folly-map.cpp
1 #include <folly/concurrency/ConcurrentHashMap.h>
2 #include <folly/AtomicHashMap.h>
3 #include <folly/AtomicUnorderedMap.h>
4
5
6 #include <chrono>
7 #include <cassert>
8 #include <iostream>
9 #include <memory>
10
11 namespace {
12
13 const unsigned s_nInsertPercentage = 10;
14 const char* kTestName = "InsDelFind";
15
16 const size_t kConcurrentHashMapSize = 10000;
17 const size_t kConcurrentHashMapPassCount = 36000;
18 const char* kConcurrentHashMapBenchmarkName = "FollyConcurrentHashMap";
19
20 const size_t kAtomicHashMapSize = 10000;
21 const size_t kAtomicHashMapPassCount = 250000;
22 const char* kAtomicHashMapBenchmarkName = "FollyAtomicHashMap";
23
24 const size_t kAtomicUnorderedInsertMapSize = 10000;
25 const size_t kAtomicUnorderedInsertMapPassCount = 500000;
26 const char* kAtomicUnorderedInsertMapBenchmarkName =
27     "FollyAtomicUnorderedInsertMap";
28
29 typedef folly::ConcurrentHashMap<size_t, size_t> ConcurrentHashMap;
30 typedef folly::AtomicHashMap<size_t, size_t> AtomicHashMap;
31 typedef folly::AtomicUnorderedInsertMap64<size_t, size_t>
32     AtomicUnorderedInsertMap;
33 }
34
35 template <typename Key>
36 bool map_contains(const AtomicUnorderedInsertMap* map, Key key) {
37   return map->find(key) != map->cend();
38 }
39
40 template <typename Key>
41 bool map_contains(const ConcurrentHashMap* map, Key key) {
42   return map->find(key) != map->cend();
43 }
44
45 template <typename Map, typename Key>
46 bool map_contains(const Map* map, Key key) {
47   return map->find(key) != map->end();
48 }
49
50 template <typename Map>
51 void run_atomic_unordered_insert_map(size_t map_size, size_t pass_count,
52                                      const char* bench_name) {
53     std::cout << "[ RUN      ] " << kTestName << "." << bench_name << std::endl;
54     auto start_time = std::chrono::system_clock::now();
55
56     size_t nInsertedNum = 0;
57     size_t nFindSuccess = 0;
58     std::unique_ptr<Map> map(new Map(map_size));
59     for (size_t count = 0; count < pass_count; count++) {
60         for (size_t i = 0; i < map_size; ++i) {
61             // The number to operate on the map.
62             size_t n = map_size + i;
63             // Insert
64             if (i % s_nInsertPercentage == 1) {
65                 auto iter = map->find(i);
66                 if (iter != map->cend()) {
67                   if (iter->second == n) {
68                     map->emplace(i, n / 2);
69                   } else {
70                     map->emplace(i, n);
71                   }
72                 } else {
73                   map->emplace(i, n);
74                 }
75                 nInsertedNum++;
76             }
77             // Find
78             {
79                 if (map_contains(map.get(), i)) {
80                     ++nFindSuccess;
81 //                    std::cout << "Found" << i << "\n";
82                 }
83             }
84         }
85     }
86     auto finish_time = std::chrono::system_clock::now();
87     auto dur = finish_time - start_time;
88     auto milisecs = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
89
90     if (nFindSuccess != nInsertedNum) {
91         std::cout << "nFindSuccess=" << nFindSuccess << ", nInsertedNum="
92                   << nInsertedNum << std::endl;
93         std::cout << "[       FAILED ] " << kTestName << "." << bench_name
94                   << " (" << milisecs.count() << " ms)" << std::endl;
95         assert(false && "ConcurrentMap ERROR");
96     } else {
97         std::cout << "[       OK ] " << kTestName << "." << bench_name
98                   << " (" << milisecs.count() << " ms)" << std::endl;
99     }
100 }
101
102 template <typename Map>
103 void run_atomic_hashmap(size_t map_size, size_t pass_count, const char* bench_name) {
104     std::cout << "[ RUN      ] " << kTestName << "." << bench_name << std::endl;
105     auto start_time = std::chrono::system_clock::now();
106
107     size_t nInsertedNum = 0;
108     size_t nFindSuccess = 0;
109     std::unique_ptr<Map> map(new Map(map_size));
110     for (size_t count = 0; count < pass_count; count++) {
111         for (size_t i = 0; i < map_size; ++i) {
112             // The number to operate on the map.
113             size_t n = map_size + i;
114             // Insert
115             if (i % s_nInsertPercentage == 1) {
116                 auto iter = map->find(i);
117                 if (iter != map->end()) {
118                   if (iter->second == n) {
119                     iter->second = n / 2;
120                   } else {
121                     iter->second = n;
122                   }
123                 } else {
124                   map->insert({i, n});
125                 }
126                 nInsertedNum++;
127             }
128             // Find
129             {
130                 if (map_contains(map.get(), i)) {
131                     ++nFindSuccess;
132 //                    std::cout << "Found" << i << "\n";
133                 }
134             }
135         }
136     }
137     auto finish_time = std::chrono::system_clock::now();
138     auto dur = finish_time - start_time;
139     auto milisecs = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
140
141     if (nFindSuccess != nInsertedNum) {
142         std::cout << "nFindSuccess=" << nFindSuccess << ", nInsertedNum="
143                   << nInsertedNum << std::endl;
144         std::cout << "[       FAILED ] " << kTestName << "." << bench_name
145                   << " (" << milisecs.count() << " ms)" << std::endl;
146         assert(false && "ConcurrentMap ERROR");
147     } else {
148         std::cout << "[       OK ] " << kTestName << "." << bench_name
149                   << " (" << milisecs.count() << " ms)" << std::endl;
150     }
151 }
152
153 template <typename Map>
154 void run_concurrent_hashmap(size_t map_size, size_t pass_count,
155                             const char* bench_name) {
156     std::cout << "[ RUN      ] " << kTestName << "." << bench_name << std::endl;
157     auto start_time = std::chrono::system_clock::now();
158
159     size_t nInsertedNum = 0;
160     size_t nFindSuccess = 0;
161     std::unique_ptr<Map> map(new Map(map_size));
162     for (size_t count = 0; count < pass_count; count++) {
163         for (size_t i = 0; i < map_size; ++i) {
164             // The number to operate on the map.
165             size_t n = map_size + i;
166             // Insert
167             if (i % s_nInsertPercentage == 1) {
168                   auto iter = map->insert({i, n});
169                   nInsertedNum++;
170 //              std::cout << "Inserted" << i << "\n";
171             }
172             // Find
173             {
174                 if (map_contains(map.get(), i)) {
175                     ++nFindSuccess;
176 //                    std::cout << "Found" << i << "\n";
177                 }
178             }
179             // Delete
180             if (i % s_nInsertPercentage == 1) {
181                 if (map_contains(map.get(), i)) {
182                     map->erase(i);
183 //                    std::cout << "Erased" << i << "\n";
184                 }
185             }
186         }
187     }
188     auto finish_time = std::chrono::system_clock::now();
189     auto dur = finish_time - start_time;
190     auto milisecs = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
191
192     if (nFindSuccess != nInsertedNum) {
193         std::cout << "nFindSuccess=" << nFindSuccess << ", nInsertedNum="
194                   << nInsertedNum << std::endl;
195         std::cout << "[       FAILED ] " << kTestName << "." << bench_name
196                   << " (" << milisecs.count() << " ms)" << std::endl;
197         assert(false && "ConcurrentMap ERROR");
198     } else {
199         std::cout << "[       OK ] " << kTestName << "." << bench_name
200                   << " (" << milisecs.count() << " ms)" << std::endl;
201     }
202 }
203
204 int main() {
205   run_concurrent_hashmap<ConcurrentHashMap>(
206           kConcurrentHashMapSize,
207           kConcurrentHashMapPassCount,
208           kConcurrentHashMapBenchmarkName);
209   run_atomic_hashmap<AtomicHashMap>(
210           kAtomicHashMapSize,
211           kAtomicHashMapPassCount,
212           kAtomicHashMapBenchmarkName);
213   run_atomic_unordered_insert_map<AtomicUnorderedInsertMap>(
214           kAtomicUnorderedInsertMapSize,
215           kAtomicUnorderedInsertMapPassCount,
216           kAtomicUnorderedInsertMapBenchmarkName);
217
218   return 0;
219 }