diff options
Diffstat (limited to 'misc/matrix_perf.cpp')
-rw-r--r-- | misc/matrix_perf.cpp | 511 |
1 files changed, 511 insertions, 0 deletions
diff --git a/misc/matrix_perf.cpp b/misc/matrix_perf.cpp new file mode 100644 index 0000000..40b03c0 --- /dev/null +++ b/misc/matrix_perf.cpp @@ -0,0 +1,511 @@ + +#include <cstdlib> +#include <iostream> +#include <sys/time.h> + +#include <mdds/mixed_type_matrix.hpp> +#include <mdds/multi_type_matrix.hpp> + +double get_current_time() +{ +#ifdef _WIN32 + FILETIME ft; + __int64 *time64 = reinterpret_cast<__int64 *>(&ft); + GetSystemTimeAsFileTime(&ft); + return *time64 / 10000000.0; +#else + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; +#endif +} + +class stack_watch +{ +public: + explicit stack_watch() : m_start_time(get_current_time()) {} + void reset() { m_start_time = get_current_time(); } + double get_duration() const { return get_current_time() - m_start_time; } + +private: + double m_start_time; +}; + +using namespace std; + +typedef mdds::mixed_type_matrix<std::string, bool> mixed_mx_type; +typedef mdds::multi_type_matrix<mdds::mtm::std_string_traits> multi_mx_type; + +namespace { + +class sum_all_values +{ + double m_sum; +public: + sum_all_values() : m_sum(0.0) {} + void operator() (const multi_mx_type::element_block_node_type& blk) + { + if (!blk.data) + return; + + if (mdds::mtv::get_block_type(*blk.data) != mdds::mtv::element_type_double) + return; + + using mdds::mtv::double_element_block; + numeric_element_block::const_iterator it = numeric_element_block::begin(*blk.data); + numeric_element_block::const_iterator it_end = numeric_element_block::end(*blk.data); + for (; it != it_end; ++it) + m_sum += *it; + } + + double get() const { return m_sum; } +}; + +class count_all_values +{ + long m_count; +public: + count_all_values() : m_count(0) {} + void operator() (const multi_mx_type::element_block_node_type& blk) + { + if (!blk.data) + return; + + if (mdds::mtv::get_block_type(*blk.data) != mdds::mtv::element_type_double) + return; + + m_count += blk.size; + } + + long get() const { return m_count; } +}; + +template<typename _Mx> +void init_manual_loop(_Mx& mx, size_t row_size, size_t col_size) +{ + double val = 0.0; + for (size_t row = 0; row < row_size; ++row) + { + for (size_t col = 0; col < col_size; ++col) + { + mx.set(row, col, val); + val += 0.00001; + } + } +} + +void init_value_vector(vector<double>& vals, size_t row_size, size_t col_size) +{ + vals.reserve(row_size*col_size); + + double val = 0.0; + for (size_t row = 0; row < row_size; ++row) + { + for (size_t col = 0; col < col_size; ++col) + { + vals.push_back(val); + val += 0.00001; + } + } +} + +template<typename _Mx> +double sum_manual_loop(const _Mx& mx, size_t row_size, size_t col_size) +{ + double sum = 0.0; + for (size_t row = 0; row < row_size; ++row) + for (size_t col = 0; col < col_size; ++col) + sum += mx.get_numeric(row, col); + + return sum; +} + +double sum_iterator(const mixed_mx_type& mx) +{ + double sum = 0.0; + mixed_mx_type::const_iterator it = mx.begin(), it_end = mx.end(); + for (; it != it_end; ++it) + { + if (it->m_type == mdds::element_numeric) + sum += it->m_numeric; + } + return sum; +} + +} + +void perf_construction() +{ + cout << "---" << endl; + size_t row_size = 20000, col_size = 8000; + { + stack_watch sw; + mixed_mx_type mx(row_size, col_size, mdds::matrix_density_filled_zero); + cout << "construction filled zero: " << sw.get_duration() << " sec (mixed_type_matrix, filled)" << endl; + } + + { + stack_watch sw; + mixed_mx_type mx(row_size, col_size, mdds::matrix_density_sparse_zero); + cout << "construction filled zero: " << sw.get_duration() << " sec (mixed_type_matrix, sparse)" << endl; + } + + { + stack_watch sw; + multi_mx_type mx(row_size, col_size, 0.0); + cout << "construction filled zero: " << sw.get_duration() << " sec (multi_type_matrix)" << endl; + } + + { + stack_watch sw; + mixed_mx_type mx(row_size, col_size, mdds::matrix_density_filled_empty); + cout << "construction filled empty: " << sw.get_duration() << " sec (mixed_type_matrix, filled)" << endl; + } + + { + stack_watch sw; + mixed_mx_type mx(row_size, col_size, mdds::matrix_density_sparse_empty); + cout << "construction filled empty: " << sw.get_duration() << " sec (mixed_type_matrix, sparse)" << endl; + } + + { + stack_watch sw; + multi_mx_type mx(row_size, col_size); + cout << "construction filled empty: " << sw.get_duration() << " sec (multi_type_matrix)" << endl; + } +} + +void perf_insertion() +{ + cout << "---" << endl; + size_t row_size = 10000; + size_t col_size = 1000; + { + mixed_mx_type mx(row_size, col_size, mdds::matrix_density_filled_zero); + stack_watch sw; + init_manual_loop(mx, row_size, col_size); + cout << "insertion via loop: " << sw.get_duration() << " sec (mixed_type_matrix, filled zero)" << endl; + } + + { + multi_mx_type mx(row_size, col_size); + stack_watch sw; + init_manual_loop(mx, row_size, col_size); + cout << "insertion via loop: " << sw.get_duration() << " sec (multi_type_matrix, init empty)" << endl; + } + + { + multi_mx_type mx(row_size, col_size, 0.0); + stack_watch sw; + init_manual_loop(mx, row_size, col_size); + cout << "insertion via loop: " << sw.get_duration() << " sec (multi_type_matrix, init zero)" << endl; + } + + { + multi_mx_type mx(row_size, col_size); + std::vector<double> vals; + + stack_watch sw; + init_value_vector(vals, row_size, col_size); + mx.set(0, 0, vals.begin(), vals.end()); + cout << "insertion via single set call: " << sw.get_duration() << " sec (multi_type_matrix, init empty, value initialization included)" << endl; + } + + { + multi_mx_type mx(row_size, col_size); + std::vector<double> vals; + init_value_vector(vals, row_size, col_size); + + stack_watch sw; + mx.set(0, 0, vals.begin(), vals.end()); + cout << "insertion via single set call: " << sw.get_duration() << " sec (multi_type_matrix, init empty, value initialization excluded)" << endl; + } + + { + multi_mx_type mx(row_size, col_size, 0.0); + std::vector<double> vals; + vals.reserve(row_size*col_size); + + stack_watch sw; + init_value_vector(vals, row_size, col_size); + mx.set(0, 0, vals.begin(), vals.end()); + cout << "insertion via single set call: " << sw.get_duration() << " sec (multi_type_matrix, init zero, value initialization included)" << endl; + } + + { + multi_mx_type mx(row_size, col_size, 0.0); + std::vector<double> vals; + init_value_vector(vals, row_size, col_size); + + stack_watch sw; + mx.set(0, 0, vals.begin(), vals.end()); + cout << "insertion via single set call: " << sw.get_duration() << " sec (multi_type_matrix, init zero, value initialization excluded)" << endl; + } +} + +void perf_sum_all_values() +{ + cout << "---" << endl; + size_t row_size = 10000; + size_t col_size = 1000; + { + mixed_mx_type mx(row_size, col_size, mdds::matrix_density_filled_zero); + init_manual_loop(mx, row_size, col_size); + + { + stack_watch sw; + double sum = sum_manual_loop(mx, row_size, col_size); + cout << "sum all values (" << sum << ") : " << sw.get_duration() << " sec (mixed_type_matrix, manual loop)" << endl; + } + + { + stack_watch sw; + double sum = sum_iterator(mx); + cout << "sum all values (" << sum << ") : " << sw.get_duration() << " sec (mixed_type_matrix, iterator)" << endl; + } + + { + stack_watch sw; + long count = 0; + for (size_t row = 0; row < row_size; ++row) + for (size_t col = 0; col < col_size; ++col) + { + if (mx.get_type(row, col) == mdds::element_numeric) + ++count; + } + + cout << "count all values (" << count << ") : " << sw.get_duration() << " sec (mixed_type_matrix, manual loop)" << endl; + } + + { + stack_watch sw; + long count = 0; + mixed_mx_type::const_iterator it = mx.begin(), it_end = mx.end(); + for (; it != it_end; ++it) + { + if (it->m_type == mdds::element_numeric) + ++count; + } + + cout << "count all values (" << count << ") : " << sw.get_duration() << " sec (mixed_type_matrix, iterator)" << endl; + } + } + + { + multi_mx_type mx(row_size, col_size, 0.0); + init_manual_loop(mx, row_size, col_size); + + { + stack_watch sw; + double sum = sum_manual_loop(mx, row_size, col_size); + cout << "sum all values (" << sum << ") : " << sw.get_duration() << " sec (multi_type_matrix, manual loop)" << endl; + } + + { + stack_watch sw; + sum_all_values func; + mx.walk(func); + cout << "sum all values (" << func.get() << ") : " << sw.get_duration() << " sec (multi_type_matrix, walk)" << endl; + } + + { + stack_watch sw; + count_all_values func; + mx.walk(func); + cout << "count all values (" << func.get() << ") : " << sw.get_duration() << " sec (multi_type_matrix, walk)" << endl; + } + } +} + +void perf_sum_all_values_multi_block() +{ + cout << "---" << endl; + size_t row_size = 10000; + size_t col_size = 1000; + double step = 0.00001; + { + mixed_mx_type mx(row_size, col_size, mdds::matrix_density_filled_zero); + double val = 0.0; + for (size_t row = 0; row < row_size; ++row) + { + for (size_t col = 0; col < col_size; ++col) + { + if ((col % 3) == 0) + { + mx.set_empty(row, col); + } + else + { + mx.set(row, col, val); + val += step; + } + } + } + + { + stack_watch sw; + double sum = sum_manual_loop(mx, row_size, col_size); + cout << "sum all values multi-block (" << sum << ") : " << sw.get_duration() << " sec (mixed_type_matrix, manual loop)" << endl; + } + + { + stack_watch sw; + double sum = sum_iterator(mx); + cout << "sum all values multi-block (" << sum << ") : " << sw.get_duration() << " sec (mixed_type_matrix, iterator)" << endl; + } + + { + stack_watch sw; + long count = 0; + for (size_t row = 0; row < row_size; ++row) + for (size_t col = 0; col < col_size; ++col) + { + if (mx.get_type(row, col) == mdds::element_numeric) + ++count; + } + + cout << "count all values multi-block (" << count << ") : " << sw.get_duration() << " sec (mixed_type_matrix, manual loop)" << endl; + } + + { + stack_watch sw; + long count = 0; + mixed_mx_type::const_iterator it = mx.begin(), it_end = mx.end(); + for (; it != it_end; ++it) + { + if (it->m_type == mdds::element_numeric) + ++count; + } + + cout << "count all values multi-block (" << count << ") : " << sw.get_duration() << " sec (mixed_type_matrix, iterator)" << endl; + } + } + + { + multi_mx_type mx(row_size, col_size); + double val = 0.0; + vector<double> vals; + vals.reserve(row_size); + for (size_t col = 0; col < col_size; ++col) + { + if ((col % 3) == 0) + continue; + + vals.clear(); + for (size_t row = 0; row < row_size; ++row) + { + vals.push_back(val); + val += step; + } + + mx.set(0, col, vals.begin(), vals.end()); + } + + { + stack_watch sw; + double sum = sum_manual_loop(mx, row_size, col_size); + cout << "sum all values multi-block (" << sum << ") : " << sw.get_duration() << " sec (multi_type_matrix, manual loop)" << endl; + } + + { + stack_watch sw; + sum_all_values func; + mx.walk(func); + cout << "sum all values multi-block (" << func.get() << ") : " << sw.get_duration() << " sec (multi_type_matrix, walk)" << endl; + } + + { + stack_watch sw; + count_all_values func; + mx.walk(func); + cout << "count all values multi-block (" << func.get() << ") : " << sw.get_duration() << " sec (multi_type_matrix, walk)" << endl; + } + } +} + +void perf_init_with_value() +{ + cout << "---" << endl; + size_t row_size = 10000; + size_t col_size = 2000; + double val = 12.3; + { + stack_watch sw; + mixed_mx_type mx(row_size, col_size, mdds::matrix_density_filled_zero); + for (size_t row = 0; row < row_size; ++row) + for (size_t col = 0; col < col_size; ++col) + mx.set(row, col, val); + cout << "init with value: " << sw.get_duration() << " sec (mixed_type_matrix, filled zero, manual loop)" << endl; + } + + { + stack_watch sw; + multi_mx_type mx(row_size, col_size, 0.0); + for (size_t row = 0; row < row_size; ++row) + for (size_t col = 0; col < col_size; ++col) + mx.set(row, col, val); + cout << "init with value: " << sw.get_duration() << " sec (multi_type_matrix, manual loop)" << endl; + } + + { + stack_watch sw; + multi_mx_type(row_size, col_size, val); + cout << "init with value: " << sw.get_duration() << " sec (multi_type_matrix, constructor)" << endl; + } + + { + stack_watch sw; + multi_mx_type mx(row_size, col_size); + vector<double> vals(row_size*col_size, val); + mx.set(0, 0, vals.begin(), vals.end()); + cout << "init with value: " << sw.get_duration() << " sec (multi_type_matrix, vector + set)" << endl; + } +} + +void perf_heap_vs_array() +{ + cout << "---" << endl; + size_t row_size = 20000, col_size = 3000; + { + mixed_mx_type mx(row_size, col_size, mdds::matrix_density_filled_empty); + init_manual_loop(mx, row_size, col_size); + stack_watch sw; + double sum = 0.0; + for (size_t row = 0; row < row_size; ++row) + for (size_t col = 0; col < col_size; ++col) + sum += mx.get_numeric(row, col); + cout << "sum with values on the heap (mixed_type_matrix): " << sw.get_duration() << " sec (" << sum << ")" << endl; + } + + { + mixed_mx_type mx(row_size, col_size, mdds::matrix_density_filled_zero); + init_manual_loop(mx, row_size, col_size); + stack_watch sw; + double sum = 0.0; + for (size_t row = 0; row < row_size; ++row) + for (size_t col = 0; col < col_size; ++col) + sum += mx.get_numeric(row, col); + cout << "sum with array values (mixed_type_matrix): " << sw.get_duration() << " sec (" << sum << ")" << endl; + } + + { + multi_mx_type mx(row_size, col_size, 0.0); + init_manual_loop(mx, row_size, col_size); + sum_all_values func; + stack_watch sw; + mx.walk(func); + double sum = func.get(); + cout << "sum with array values (multi_type_matrix): " << sw.get_duration() << " sec (" << sum << ")" << endl; + } +} + +int main() +{ + perf_construction(); + perf_insertion(); + perf_sum_all_values(); + perf_sum_all_values_multi_block(); + perf_init_with_value(); + perf_heap_vs_array(); + return EXIT_SUCCESS; +} |