summaryrefslogtreecommitdiffstats
path: root/misc/matrix_perf.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--misc/matrix_perf.cpp511
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;
+}