diff --git a/test_perf.cpp b/test_perf.cpp new file mode 100644 index 0000000..26d4b49 --- /dev/null +++ b/test_perf.cpp @@ -0,0 +1,174 @@ +#include "deferred_allocator.h" + +#include +#include +#include +#include +#include + +template +auto benchmark(unsigned N, Generator g) +{ + AllocatorArgument h; + Allocator a{h}; + Container c{a}; + + auto start = std::chrono::high_resolution_clock::now(); + for (unsigned i = 0; i != N; ++i) + { + c.push_back(g(h, a, i)); + } + auto stop = std::chrono::high_resolution_clock::now(); + + return std::chrono::duration(stop - start).count() / 1000.0; +} + +void write_linechart( + std::ostream & o, + std::string label, + std::string title, + std::string x_title, + std::string y_title, + std::vector legend, + std::map> series); + +unsigned const max_iterations = 5000; +unsigned const step = 20; + +void all_benchmarks(std::string html_filename) +{ + std::map> all_series; + std::map> deferred_only_series; + std::vector all_legend{"X", "vector", "vector", "deferred_vector"}; + std::vector deferred_only_legend{"X", "deferred_vector"}; + + for (unsigned i = 0; i < max_iterations; i += step) + { + auto d = benchmark, std::allocator, std::vector>>( + i, [](auto &, auto &, auto & i) { return std::make_unique(i); }); + + // std::cout << " " << i << "\t" << i / d << std::endl; + all_series[i].push_back(d ? i / d : 0); + } + + for (unsigned i = 0; i < max_iterations; i += step) + { + auto d = benchmark, std::allocator, std::vector>>( + i, [](auto &, auto &, auto & i) { return std::make_shared(i); }); + + // std::cout << " " << i << "\t" << i / d << std::endl; + all_series[i].push_back(d ? i / d : 0); + } + + for (unsigned i = 0; i < max_iterations; i += step) + { + auto d = benchmark, gcpp::deferred_vector>>( + i, [](auto & h, auto &, auto & i) { return h.template make(i); }); + + // std::cout << " " << i << "\t" << i / d << std::endl; + all_series[i].push_back(d ? i / d : 0); + deferred_only_series[i].push_back(d ? i / d : 0); + } + + { + std::ofstream o(html_filename); + write_linechart(o, "just_deferred", "Deferred only", "Number of insertions", "Insertions per second", deferred_only_legend, deferred_only_series); + write_linechart(o, "all_benchmarks", "Deferred compared to std", "Number of insertions", "Insertions per second", all_legend, all_series); + } +} + +void one_benchmark(unsigned how_many = max_iterations) +{ + auto unique_ptr_time = benchmark, std::allocator, std::vector>>( + how_many, [](auto &, auto &, auto & i) { return std::make_unique(i); }); + + auto deferred_ptr_time = benchmark, gcpp::deferred_vector>>( + how_many, [](auto & h, auto &, auto & i) { return h.template make(i); }); + + std::cout << "Inserting " << how_many << " elements into deferred_vector is " << std::setprecision(0) << (deferred_ptr_time / unique_ptr_time) + << " times slower than into vector" << std::endl; +} + +int main(int argc, char * argv[]) +{ + std::cout << std::fixed; + + if (argc == 2) + { + all_benchmarks(argv[1]); + } + else + { + one_benchmark(); + } +} + +void write_linechart( + std::ostream & o, + std::string label, + std::string title, + std::string x_title, + std::string y_title, + std::vector h, + std::map> all_series) +{ + std::string header = R"html( + + + +
+ + )html"; + + o << header; + { + for (auto v : h) + { + o << "data.addColumn('number', '" << v << "');"; + } + } + + o << "data.addRows([\n"; + + for (auto [k, v] : all_series) + { + o << "[" << k << ", "; + bool first = true; + for (auto z : v) + { + o << (first ? "" : ", ") << z; + first = false; + } + o << "],\n"; + } + o << footer << std::endl; +}