#include <junction/ConcurrentMap_Grampa.h>
+#include <junction/ConcurrentMap_Linear.h>
+#include <junction/ConcurrentMap_Leapfrog.h>
+#include <junction/ConcurrentMap_Crude.h>
#include <iostream>
#include <memory>
#include <chrono>
const unsigned s_nInsertPercentage = 10;
const char* kTestName = "InsDelFind";
+// Run GC after "kGCFrequency" operations.
+const size_t kGCFrequency = 3000;
+const size_t kLeapfrogGCFrequency = 1500;
+
+const size_t kCrudeMapSize = 10000;
+const size_t kCrudePassCount = 400000;
+const char* kCrudeBenchmarkName = "JunctionMapCrude";
+
const size_t kGrampaMapSize = 20000;
-const size_t kGrampaPassCount = 30000;
-const char* kGrampaBenchmarkName = "JunctionMapLinear";
+const size_t kGrampaPassCount = 60000;
+const char* kGrampaBenchmarkName = "JunctionMapGrampa";
+
+const size_t kLinearMapSize = 20000;
+const size_t kLinearPassCount = 70000;
+const char* kLinearBenchmarkName = "JunctionMapLinear";
+
+const size_t kLeapfrogMapSize = 20000;
+const size_t kLeapfrogPassCount = 75000;
+const char* kLeapfrogBenchmarkName = "JunctionMapLeapfrog";
} // namespace
typedef junction::ConcurrentMap_Grampa<size_t, size_t> GrampaMap;
+typedef junction::ConcurrentMap_Linear<size_t, size_t> LinearMap;
+typedef junction::ConcurrentMap_Leapfrog<size_t, size_t> LeapfrogMap;
+typedef junction::ConcurrentMap_Crude<size_t, size_t> CrudeMap;
template <typename Map>
-void run_test(size_t map_size, size_t pass_count, const char* bench_name) {
+void run_crude_map(size_t map_size, size_t pass_count, const char* bench_name,
+ size_t gc_frequency) {
+ std::cout << "[ RUN ] " << kTestName << "." << bench_name << std::endl;
auto start_time = std::chrono::system_clock::now();
size_t nInsertedNum = 0;
size_t nFindSuccess = 0;
+ size_t nOperations = 0;
+ // Seems like the crude map won't resize, so better have a large enough
+ // capacity.
+ std::unique_ptr<Map> map(new Map(map_size * 32));
+ auto qsbrContext = junction::DefaultQSBR.createContext();
+ for (size_t count = 0; count < pass_count; count++) {
+ for (size_t i = 0; i < map_size; ++i) {
+ // The number to operate on the map.
+ size_t n = map_size + i;
+ // Insert
+ if (i % s_nInsertPercentage == 1) {
+ map->assign(i, n);
+ nInsertedNum++;
+// std::cout << "Inserted" << i << "\n";
+ }
+ // Find
+ {
+ if (map->get(i)) {
+ ++nFindSuccess;
+// std::cout << "Found" << i << "\n";
+ }
+ }
+ // Delete
+ if (i % s_nInsertPercentage == 1) {
+ if (map->get(i)) {
+ map->assign(n, 0);
+// std::cout << "Erased" << i << "\n";
+ }
+ }
+ if (++nOperations > gc_frequency) {
+ junction::DefaultQSBR.update(qsbrContext);
+ nOperations = 0;
+ }
+ }
+ }
+ junction::DefaultQSBR.update(qsbrContext);
+ junction::DefaultQSBR.destroyContext(qsbrContext );
+ auto finish_time = std::chrono::system_clock::now();
+ auto dur = finish_time - start_time;
+ auto milisecs = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
+
+ if (nFindSuccess != nInsertedNum) {
+ std::cout << "nFindSuccess=" << nFindSuccess << ", nInsertedNum="
+ << nInsertedNum << std::endl;
+ std::cout << "[ FAILED ] " << kTestName << "." << bench_name
+ << "(" << milisecs.count() << " ms)" << std::endl;
+ assert(false && "ConcurrentMap ERROR");
+ } else {
+ std::cout << "[ OK ] " << kTestName << "." << bench_name
+ << "(" << milisecs.count() << " ms)" << std::endl;
+ }
+}
+
+template <typename Map>
+void run_test(size_t map_size, size_t pass_count, const char* bench_name,
+ size_t gc_frequency) {
+ std::cout << "[ RUN ] " << kTestName << "." << bench_name << std::endl;
+ auto start_time = std::chrono::system_clock::now();
+
+ size_t nInsertedNum = 0;
+ size_t nFindSuccess = 0;
+ size_t nOperations = 0;
std::unique_ptr<Map> map(new Map());
auto qsbrContext = junction::DefaultQSBR.createContext();
for (size_t count = 0; count < pass_count; count++) {
size_t n = map_size + i;
// Insert
if (i % s_nInsertPercentage == 1) {
- auto iter = map->insertOrFind(n);
+ auto iter = map->insertOrFind(i);
if (!iter.getValue()) {
iter.assignValue(n);
nInsertedNum++;
-// std::cout << "Inserted" << n << "\n";
+// std::cout << "Inserted" << i << "\n";
}
}
// Find
{
- auto iter = map->find(n);
+ auto iter = map->find(i);
if (iter.getValue()) {
++nFindSuccess;
-// std::cout << "Found" << n << "\n";
+// std::cout << "Found" << i << "\n";
}
}
// Delete
if (i % s_nInsertPercentage == 1) {
- auto iter = map->find(n);
+ auto iter = map->find(i);
if (iter.getValue()) {
iter.eraseValue();
-// std::cout << "Erased" << n << "\n";
+// std::cout << "Erased" << i << "\n";
}
}
- junction::DefaultQSBR.update(qsbrContext);
+ if (++nOperations > gc_frequency) {
+ junction::DefaultQSBR.update(qsbrContext);
+ nOperations = 0;
+ }
}
}
+ junction::DefaultQSBR.update(qsbrContext);
+ junction::DefaultQSBR.destroyContext(qsbrContext );
auto finish_time = std::chrono::system_clock::now();
auto dur = finish_time - start_time;
auto milisecs = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
if (nFindSuccess != nInsertedNum) {
std::cout << "nFindSuccess=" << nFindSuccess << ", nInsertedNum="
- << nInsertedNum << "\n";
+ << nInsertedNum << std::endl;
std::cout << "[ FAILED ] " << kTestName << "." << bench_name
- << "(" << milisecs.count() << " ms)\n";
+ << "(" << milisecs.count() << " ms)" << std::endl;
assert(false && "ConcurrentMap ERROR");
} else {
std::cout << "[ OK ] " << kTestName << "." << bench_name
- << "(" << milisecs.count() << " ms)\n";
+ << "(" << milisecs.count() << " ms)" << std::endl;
}
}
int main() {
- run_test<GrampaMap>(kGrampaMapSize, kGrampaPassCount, kGrampaBenchmarkName);
+ run_crude_map<CrudeMap>(kCrudeMapSize, kCrudePassCount, kCrudeBenchmarkName,
+ kGCFrequency);
+ run_test<LeapfrogMap>(kLeapfrogMapSize, kLeapfrogPassCount,
+ kLeapfrogBenchmarkName, kLeapfrogGCFrequency );
+ run_test<LinearMap>(kLinearMapSize, kLinearPassCount, kLinearBenchmarkName,
+ kGCFrequency);
+ run_test<GrampaMap>(kGrampaMapSize, kGrampaPassCount, kGrampaBenchmarkName,
+ kGCFrequency);
return 0;
}