132 lines
3.7 KiB
C++
132 lines
3.7 KiB
C++
#include <cstdio>
|
|
#include <cassert>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <chrono>
|
|
#include "amap.h"
|
|
#include "simap.h"
|
|
#include "mapmap.hpp"
|
|
#include "unomap.hpp"
|
|
|
|
/**
|
|
* Creates keys or returns the ith key. Used for performance tests.
|
|
*
|
|
* @param i When "create" is false, we return the ith key (does not check OOB)
|
|
* @param create When true, we initialize the keystore with keys generated from 0..i indices.
|
|
* @returns The ith key when create==false, otherwise undefined.
|
|
*/
|
|
inline const char *keystore(int i, bool create = false) noexcept {
|
|
static thread_local std::vector<std::string> keys;
|
|
|
|
if(!create) {
|
|
return keys[i].c_str();
|
|
} else {
|
|
keys.resize(0);
|
|
keys.reserve(0);
|
|
std::string key = "k";
|
|
for(int j = 0; j < i; ++j) {
|
|
keys.push_back(key + std::to_string(j));
|
|
}
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates keys or returns the ith key. Used for performance tests.
|
|
*
|
|
* @param i When "create" is false, we return the ith data (does not check OOB)
|
|
* @param create When true, we initialize the datastore with datas generated from 0..i indices.
|
|
* @returns The ith data when create==false, otherwise undefined.
|
|
*/
|
|
inline int *datastore(int i, bool create = false) noexcept {
|
|
static thread_local std::vector<int> keys;
|
|
|
|
if(!create) {
|
|
return &(keys[i]);
|
|
} else {
|
|
keys.resize(0);
|
|
keys.reserve(0);
|
|
for(int j = 0; j < i; ++j) {
|
|
keys.push_back(j);
|
|
}
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
void test_perf(amap mapdo, void *map, int max_key, const char *what) {
|
|
auto begin = std::chrono::high_resolution_clock::now();
|
|
for(int i = 0; i < max_key; ++i) {
|
|
const char *key = keystore(i);
|
|
int *data = datastore(i);
|
|
mapdo(map, AMAP_SET, key, data);
|
|
}
|
|
auto end = std::chrono::high_resolution_clock::now();
|
|
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
|
|
|
|
printf("Insertion time for %d elements (%s): %.3f ms.\n", max_key, what, elapsed.count() * 1e-6);
|
|
}
|
|
|
|
void test_basics(amap mapdo, void *map) {
|
|
/* Most basics */
|
|
assert(NULL == mapdo(map, AMAP_GET, "asdf", NULL));
|
|
int i = 42;
|
|
int *iptr;
|
|
const char *chptr;
|
|
assert(NULL != mapdo(map, AMAP_SET, "meaning", &i));
|
|
assert(NULL != (iptr = (int *)mapdo(map, AMAP_GET, "meaning", NULL)));
|
|
assert(*iptr == 42);
|
|
assert(iptr == &i);
|
|
|
|
/* Delete / tombstone */
|
|
assert(NULL != mapdo(map, AMAP_SET, "meaning", NULL));
|
|
assert(NULL == (int *)mapdo(map, AMAP_GET, "meaning", NULL));
|
|
|
|
/* Check re-adding */
|
|
assert(NULL != mapdo(map, AMAP_SET, "meaning", &i));
|
|
assert(NULL != (iptr = (int *)mapdo(map, AMAP_GET, "meaning", NULL)));
|
|
assert(*iptr == 42);
|
|
assert(iptr == &i);
|
|
|
|
/* Test Erase */
|
|
assert(NULL != mapdo(map, AMAP_ERASE, NULL, NULL));
|
|
|
|
/* Check re-adding 3 new things */
|
|
assert(NULL != mapdo(map, AMAP_SET, "meaningless1", &i));
|
|
assert(NULL != mapdo(map, AMAP_SET, "meaning2", &i));
|
|
const char *helloworld = "Hello world!";
|
|
assert(NULL != mapdo(map, AMAP_SET, "hello", (char *)helloworld)); /* ugly cast... */
|
|
|
|
assert(NULL != (chptr = (const char *)mapdo(map, AMAP_GET, "hello", NULL)));
|
|
assert(strlen(chptr) == strlen(helloworld));
|
|
assert(strcmp(chptr, helloworld) == 0);
|
|
assert(NULL != (iptr = (int *)mapdo(map, AMAP_GET, "meaning2", NULL)));
|
|
assert(*iptr == 42);
|
|
assert(iptr == &i);
|
|
assert(NULL != (iptr = (int *)mapdo(map, AMAP_GET, "meaningless1", NULL)));
|
|
assert(*iptr == 42);
|
|
assert(iptr == &i);
|
|
}
|
|
|
|
int main() {
|
|
/* Basic tests */
|
|
simap_instance si = simap_create();
|
|
test_basics(simap, &si);
|
|
|
|
mapmap_instance mi = mapmap_create();
|
|
test_basics(mapmap, &mi);
|
|
|
|
unomap_instance umi = unomap_create();
|
|
test_basics(unomap, &umi);
|
|
|
|
/* Performance tests */
|
|
int i = 100;
|
|
keystore(i, true);
|
|
datastore(i, true);
|
|
|
|
test_perf(mapmap, &mi, i, "std::map");
|
|
test_perf(simap, &si, i, "simap");
|
|
test_perf(unomap, &umi, i, "std::unordered_map");
|
|
|
|
return 0;
|
|
}
|