diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8a72bfd0e1247fcf1f803debdac2db6777d98980..17a5f1872146987c5cd5a684a53523ea0674d469 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ add_library(hashtable STATIC hashtable.cpp) -add_executable(main main.cpp) -target_link_libraries(main hashtable) +add_executable(benchmark benchmark.cpp) +target_link_libraries(benchmark hashtable) diff --git a/src/benchmark.cpp b/src/benchmark.cpp new file mode 100644 index 0000000000000000000000000000000000000000..28196c27a461d9779b9c5dd2414de3adf4c75298 --- /dev/null +++ b/src/benchmark.cpp @@ -0,0 +1,151 @@ +#include <chrono> +#include <string> +#include <utility> +#include <cstdlib> +#include <iostream> +#include <exception> + +#include "hashtable.h" + +using std::cout; +using std::cerr; +using std::endl; +using std::pair; +using std::string; + +using std::chrono::steady_clock; +using duration = std::chrono::duration<double>; + + +const unsigned runs = 10; +const unsigned rseed = 12975033; + +void print_usage(const string &pname) { + cerr << "Usage: " << pname << " N" << endl; + cerr << "Where N is an integer greater than zero." << endl; +} + +template <typename Tabletype> +pair<double,string> benchmark_linearinsertion(unsigned n, float alpha, float s) { + duration measurement = duration::zero(); + string tableinfo; + + for (unsigned i=0; i<runs; i++) { + auto start = steady_clock::now(); + + Tabletype hashtable(0, alpha, s); + for (unsigned j=1; j<=n; j++) { + hashtable.insert(j); + } + + measurement += steady_clock::now() - start; + tableinfo = hashtable.info(); + } + + return { measurement.count()/runs, tableinfo }; +} + +int main(int argc, char *argv[]) +{ + long n; + const string pname(argv[0]); + pair<double,string> result; + + if (argc != 2) { + print_usage(pname); + return 1; + } + + if (argc == 2 && (string("-h") == argv[1] || string("--help") == argv[1])) { + print_usage(pname); + return 1; + } + + try { n = std::stol(argv[1]); } + catch (const std::exception &ex) { + print_usage(pname); + return 1; + } + + if (n <= 0) { + print_usage(pname); + return 1; + } + + cout << "Inserting integers from 1 to " << n << " into different hashtables." << endl; + cout << "All measurements are averages over " << runs << " runs." << endl << endl; + + cout << "Table: hashing by division, linear probing, alpha: " << 0.5 << ", s: " << 2 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntDivHashing,LinearProbing>>(n, 0.5, 2); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by division, linear probing, alpha: " << 0.5 << ", s: " << 4 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntDivHashing,LinearProbing>>(n, 0.5, 4); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by division, linear probing, alpha: " << 0.75 << ", s: " << 2 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntDivHashing,LinearProbing>>(n, 0.75, 2); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by division, quadratic probing, alpha: " << 0.5 << ", s: " << 2 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntDivHashing,QuadraticProbing>>(n, 0.5, 2); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by division, quadratic probing, alpha: " << 0.5 << ", s: " << 4 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntDivHashing,QuadraticProbing>>(n, 0.5, 4); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by division, quadratic probing, alpha: " << 0.75 << ", s: " << 2 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntDivHashing,QuadraticProbing>>(n, 0.75, 2); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by division, double hashing, alpha: " << 0.5 << ", s: " << 2 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntDivHashing,DoubleHashing>>(n, 0.5, 2); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by division, double hashing, alpha: " << 0.5 << ", s: " << 4 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntDivHashing,DoubleHashing>>(n, 0.5, 4); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by division, double hashing, alpha: " << 0.75 << ", s: " << 2 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntDivHashing,DoubleHashing>>(n, 0.75, 2); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by multiplication, linear probing, alpha: " << 0.5 << ", s: " << 2 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntMulHashing,LinearProbing>>(n, 0.5, 2); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by multiplication, linear probing, alpha: " << 0.5 << ", s: " << 4 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntMulHashing,LinearProbing>>(n, 0.5, 4); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by multiplication, linear probing, alpha: " << 0.75 << ", s: " << 2 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntMulHashing,LinearProbing>>(n, 0.75, 2); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by multiplication, quadratic probing, alpha: " << 0.5 << ", s: " << 2 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntMulHashing,QuadraticProbing>>(n, 0.5, 2); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by multiplication, quadratic probing, alpha: " << 0.5 << ", s: " << 4 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntMulHashing,QuadraticProbing>>(n, 0.5, 4); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by multiplication, quadratic probing, alpha: " << 0.75 << ", s: " << 2 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntMulHashing,QuadraticProbing>>(n, 0.75, 2); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by multiplication, double hashing, alpha: " << 0.5 << ", s: " << 2 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntMulHashing,DoubleHashing>>(n, 0.5, 2); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by multiplication, double hashing, alpha: " << 0.5 << ", s: " << 4 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntMulHashing,DoubleHashing>>(n, 0.5, 4); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + cout << "Table: hashing by multiplication, double hashing, alpha: " << 0.75 << ", s: " << 2 << endl;; + result = benchmark_linearinsertion<IntegerTable<IntMulHashing,DoubleHashing>>(n, 0.75, 2); + cout << "Time: " << result.first << "s, " << result.second << endl << endl; + + return 0; +} diff --git a/src/hashing.h b/src/hashing.h index 5773504962e0a61c523cb366de12cb76dba66c53..4372b8293ab9cb90155fcc5998ace16192dc6a1d 100644 --- a/src/hashing.h +++ b/src/hashing.h @@ -16,6 +16,8 @@ class DivHashing { size_t m; }; +using IntDivHashing = DivHashing<unsigned int>; + /* * hashing by multiplication */ @@ -29,6 +31,9 @@ class MulHashing { size_t m; }; +using IntMulHashing = MulHashing<unsigned int>; + + /* * linear probing */ diff --git a/src/hashtable.h b/src/hashtable.h index 1d394a99bae945f7f904c00cab22eaf31365016d..2d9133048099f24e2915a8b6393ceec49ddec134 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -56,4 +56,7 @@ template class Hashtable<unsigned int, MulHashing<unsigned int>, LinearProbing>; template class Hashtable<unsigned int, MulHashing<unsigned int>, QuadraticProbing>; template class Hashtable<unsigned int, MulHashing<unsigned int>, DoubleHashing>; + +template <typename H, typename P> using IntegerTable = Hashtable<unsigned, H, P>; + #endif diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index 3baea48d6c4127fb3129228e50b4ae4a987465f9..0000000000000000000000000000000000000000 --- a/src/main.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include <iostream> - -int main() { - std::cout << "Hello CMake." << std::endl; -} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d02f383fa9f56fea859486bf6d374af5df944739..a2a1292328ad55d3cde48ae9af44fc1b3c52d56e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,16 +5,13 @@ add_subdirectory(/usr/src/gtest ${PROJECT_BINARY_DIR}/gtest) include(CTest) # the executables that run the tests -add_executable(test_main test_main.cpp) add_executable(test_hashing test_hashing.cpp) add_executable(test_hashtable test_constructor.cpp test_hashtable.cpp) # link needed libraries -target_link_libraries(test_main gtest gtest_main) target_link_libraries(test_hashing gtest gtest_main) target_link_libraries(test_hashtable hashtable gtest gtest_main) # run with ctest -add_test(NAME test_main COMMAND ${EXECUTABLE_OUTPUT_PATH}/test_main) add_test(NAME test_hashing COMMAND ${EXECUTABLE_OUTPUT_PATH}/test_hashing) add_test(NAME test_hashtable COMMAND ${EXECUTABLE_OUTPUT_PATH}/test_hashtable) diff --git a/tests/test_main.cpp b/tests/test_main.cpp deleted file mode 100644 index 21805333f00ab2827051c701f08d1b4b2ea1cf0d..0000000000000000000000000000000000000000 --- a/tests/test_main.cpp +++ /dev/null @@ -1 +0,0 @@ -#include <gtest/gtest.h>