diff --git a/experimental/bench_segmented_algos.cpp b/experimental/bench_segmented_algos.cpp index a3febbf..c2f5d7a 100644 --- a/experimental/bench_segmented_algos.cpp +++ b/experimental/bench_segmented_algos.cpp @@ -30,11 +30,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -43,12 +45,14 @@ #include #include #include +#include #include #include #include #include #include + using boost::move_detail::cpu_timer; using boost::move_detail::cpu_times; using boost::move_detail::nanosecond_type; @@ -201,6 +205,13 @@ struct is_negative bool operator()(const T& x) const { return int_value(x) < 0; } }; +template +struct is_zero_or_positive +{ + bool operator()(const T& x) const { return int_value(x) >= 0; } +}; + + template struct counter { @@ -209,6 +220,42 @@ struct counter T operator()() { return T(n++); } }; +template +class equal_to_stored +{ + typedef T value_type; + const value_type t_; + + public: + BOOST_CONTAINER_FORCEINLINE explicit equal_to_stored(const value_type &t) + : t_(t) + {} + + template + BOOST_CONTAINER_FORCEINLINE bool operator()(const U &t)const + { + return t_ == t; + } +}; + +template +class unequal_to_stored +{ + typedef T value_type; + const value_type t_; + + public: + BOOST_CONTAINER_FORCEINLINE explicit unequal_to_stored(const value_type &t) + : t_(t) + {} + + template + BOOST_CONTAINER_FORCEINLINE bool operator()(const U &t)const + { + return t_ != t; + } +}; + ////////////////////////////////////////////////////////////////////////////// // C++03 fallbacks for C++11-only functions ////////////////////////////////////////////////////////////////////////////// @@ -528,6 +575,34 @@ void bench_find_if(C& c, std::size_t iters, const char* cname, print_ratio(label, cname, r1, r2); } +template +void bench_find_if_not(C& c, std::size_t iters, const char* cname, + Pred pred, const char* label) +{ + int result = 0; + + cpu_timer t1; + for (std::size_t i = 0; i < iters; ++i) { + t1.resume(); + typename C::iterator it = std::find_if_not(c.begin(), c.end(), pred); + result = (it != c.end()) ? int_value(*it) : -1; + t1.stop(); + } + escape(&result); + double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); + + cpu_timer t2; + for (std::size_t i = 0; i < iters; ++i) { + t2.resume(); + typename C::iterator it = bc::segmented_find_if_not(c.begin(), c.end(), pred); + result = (it != c.end()) ? int_value(*it) : -1; + t2.stop(); + } + escape(&result); + double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); + print_ratio(label, cname, r1, r2); +} + template void bench_equal(C& c, C& c2, std::size_t iters, const char* cname, const char* label) @@ -1051,6 +1126,62 @@ void bench_search_n(C& c, std::size_t iters, const char* cname, print_ratio(label, cname, r1, r2); } +template +void bench_partition(C& c, std::size_t iters, const char* cname, + Pred pred, const char* label) +{ + int result = 0; + + cpu_timer t1; + for (std::size_t i = 0; i < iters; ++i) { + t1.resume(); + typename C::iterator it = std::partition(c.begin(), c.end(), pred); + result = (it == c.end()) ? 1 : 0; + t1.stop(); + } + escape(&result); + double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); + + cpu_timer t2; + for (std::size_t i = 0; i < iters; ++i) { + t2.resume(); + typename C::iterator it = bc::segmented_partition(c.begin(), c.end(), pred); + result = (it == c.end()) ? 1 : 0; + t2.stop(); + } + escape(&result); + double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); + print_ratio(label, cname, r1, r2); +} + +template +void bench_stable_partition(C& c, std::size_t iters, const char* cname, + Pred pred, const char* label) +{ + int result = 0; + + cpu_timer t1; + for (std::size_t i = 0; i < iters; ++i) { + t1.resume(); + typename C::iterator it = std::stable_partition(c.begin(), c.end(), pred); + result = (it == c.end()) ? 1 : 0; + t1.stop(); + } + escape(&result); + double r1 = calc_ns_per_elem(t1.elapsed().wall, iters, c.size()); + + cpu_timer t2; + for (std::size_t i = 0; i < iters; ++i) { + t2.resume(); + typename C::iterator it = bc::segmented_stable_partition(c.begin(), c.end(), pred); + result = (it == c.end()) ? 1 : 0; + t2.stop(); + } + escape(&result); + double r2 = calc_ns_per_elem(t2.elapsed().wall, iters, c.size()); + print_ratio(label, cname, r1, r2); +} + template void bench_partition_copy(C& c, std::size_t iters, const char* cname) { @@ -1091,27 +1222,79 @@ void run_all(C& c, std::size_t iters, const char* cname) { typedef typename C::value_type VT; + //Make backup for algorithms that modify the container + C c_original = c; + + //for_each bench_for_each(c, iters, cname); + + //copy bench_copy(c, iters, cname); + + //copy_if bench_copy_if(c, iters, cname, is_odd(), "copy_if(hit)"); bench_copy_if(c, iters, cname, is_negative(), "copy_if(miss)"); - bench_copy_n(c, iters, cname); - bench_fill(c, iters, cname); - bench_fill_n(c, iters, cname); - bench_generate(c, iters, cname); - bench_generate_n(c, iters, cname); - bench_count(c, iters, cname, VT(-1), "count(miss)"); + //copy_n + bench_copy_n(c, iters, cname); + + //count bench_count(c, iters, cname, VT(0), "count(hit)"); + bench_count(c, iters, cname, VT(-1), "count(miss)"); + + //count_if bench_count_if(c, iters, cname, is_odd(), "count_if(hit)"); bench_count_if(c, iters, cname, is_negative(), "count_if(miss)"); - bench_find(c, iters, cname, VT(-1), "find(miss)"); + //find bench_find(c, iters, cname, VT(static_cast(c.size() / 2)), "find(hit)"); - bench_find_if(c, iters, cname, is_odd(), "find_if(hit)"); + bench_find(c, iters, cname, VT(-1), "find(miss)"); + + //find_if + bench_find_if(c, iters, cname, equal_to_stored(VT(static_cast(c.size() / 2))), "find_if(hit)"); bench_find_if(c, iters, cname, is_negative(), "find_if(miss)"); - { + //find_if_not + bench_find_if_not(c, iters, cname, unequal_to_stored(VT(static_cast(c.size() / 2))), "find_if_not(hit)"); + bench_find_if_not(c, iters, cname, is_zero_or_positive(), "find_if_not(miss)"); + + //search_n + bench_search_n(c, iters, cname, 1, VT(static_cast(c.size() / 2)), "search_n(hit)"); + bench_search_n(c, iters, cname, 3, VT(-1), "search_n(miss)"); + + { //is_sorted + bench_is_sorted(c, iters, cname, "is_sorted(hit)"); + C c2(c); + typename C::iterator last = c2.end(); + --last; + *last = VT(0); + bench_is_sorted(c2, iters, cname, "is_sorted(miss)"); + } + { //is_partitioned + bench_is_partitioned(c, iters, cname, is_negative(), "is_partitioned(hit)"); + C c2(c); + typename C::iterator last = c2.end(); + --last; + *last = VT(-1); + bench_is_partitioned(c2, iters, cname, is_negative(), "is_partitioned(miss)"); + } + { // fill + C c2(c); + bench_fill(c2, iters, cname); + } + { // fill_n + C c2(c); + bench_fill_n(c2, iters, cname); + } + { // generate + C c2(c); + bench_generate(c2, iters, cname); + } + { //generate_n + C c2(c); + bench_generate_n(c2, iters, cname); + } + { //equal C c2(c); bench_equal(c, c2, iters, cname, "equal(hit)"); typename C::iterator last = c2.end(); @@ -1119,54 +1302,60 @@ void run_all(C& c, std::size_t iters, const char* cname) *last = VT(-1); bench_equal(c, c2, iters, cname, "equal(miss)"); } - - { - VT miss_pat[] = {VT(-1), VT(-2), VT(-3)}; - bench_search(c, iters, cname, miss_pat, 3, "search(miss)"); + { //search int half = static_cast(c.size() / 2); VT hit_pat[] = {VT(half), VT(half + 1), VT(half + 2)}; bench_search(c, iters, cname, hit_pat, 3, "search(hit)"); - } - bench_search_n(c, iters, cname, 3, VT(-1), "search_n(miss)"); - bench_search_n(c, iters, cname, 1, VT(static_cast(c.size() / 2)), "search_n(hit)"); - - bench_is_sorted(c, iters, cname, "is_sorted(hit)"); - { - C c2(c); - typename C::iterator last = c2.end(); - --last; - *last = VT(0); - bench_is_sorted(c2, iters, cname, "is_sorted(miss)"); + VT miss_pat[] = {VT(-1), VT(-2), VT(-3)}; + bench_search(c, iters, cname, miss_pat, 3, "search(miss)"); } - bench_is_partitioned(c, iters, cname, is_negative(), "is_partitioned(hit)"); - { - C c2(c); - typename C::iterator last = c2.end(); - --last; - *last = VT(-1); - bench_is_partitioned(c2, iters, cname, is_negative(), "is_partitioned(miss)"); - } - - bench_remove(c, iters, cname, VT(-1), "remove(miss)"); + //remove bench_remove(c, iters, cname, VT(0), "remove(hit)"); - bench_remove_if(c, iters, cname, is_negative(), "remove_if(miss)"); - bench_remove_if(c, iters, cname, is_odd(), "remove_if(hit)"); - bench_remove_copy(c, iters, cname, VT(-1), "remove_copy(miss)"); - bench_remove_copy(c, iters, cname, VT(0), "remove_copy(hit)"); - bench_remove_copy_if(c, iters, cname, is_negative(), "remove_copy_if(miss)"); - bench_remove_copy_if(c, iters, cname, is_odd(), "remove_copy_if(hit)"); + bench_remove(c, iters, cname, VT(-1), "remove(miss)"); - bench_replace(c, iters, cname, VT(-1), VT(-2), "replace(miss)"); + //remove_if + bench_remove_if(c, iters, cname, is_odd(), "remove_if(hit)"); + bench_remove_if(c, iters, cname, is_negative(), "remove_if(miss)"); + + //remove_copy + bench_remove_copy(c, iters, cname, VT(0), "remove_copy(hit)"); + bench_remove_copy(c, iters, cname, VT(-1), "remove_copy(miss)"); + + //remove_copy_if + bench_remove_copy_if(c, iters, cname, is_odd(), "remove_copy_if(hit)"); + bench_remove_copy_if(c, iters, cname, is_negative(), "remove_copy_if(miss)"); + + //replace bench_replace(c, iters, cname, VT(0), VT(0), "replace(hit)"); + bench_replace(c, iters, cname, VT(-1), VT(-2), "replace(miss)"); + + //replace_if bench_replace_if(c, iters, cname, is_odd(), VT(-2), "replace_if(hit)"); bench_replace_if(c, iters, cname, is_negative(), VT(-2), "replace_if(miss)"); + //reverse bench_reverse(c, iters, cname); + + //reverse_copy bench_reverse_copy(c, iters, cname); + + //swap_ranges bench_swap_ranges(c, iters, cname); - bench_partition_copy(c, iters, cname); + + //bench_search bench_transform(c, iters, cname); + + //partition_copy + bench_partition_copy(c, iters, cname); + + //partition + bench_partition(c, iters, cname, is_odd(), "partition(hit)"); + bench_partition(c, iters, cname, is_negative(), "partition(miss)"); + + //stable_partition + bench_stable_partition(c, iters, cname, is_odd(), "stable_partition(hit)"); + bench_stable_partition(c, iters, cname, is_negative(), "stable_partition(miss)"); } ////////////////////////////////////////////////////////////////////////////// @@ -1186,15 +1375,14 @@ void run_benchmarks() std::cout << "\n=== Segmented algorithm benchmark [" << typeid(T).name() << "] ===\n" << "Elements: " << N << " Iterations: " << iter << "\n\n"; - + { std::cout << "--- bc::deque<" << typeid(T).name() << "> ---\n"; bc::deque dq; fill_test_data(dq, N); run_all(dq, iter, "deque"); std::cout << "\n"; - } - /* + }/* { std::cout << "--- bc::nest<" << typeid(T).name() << "> ---\n"; bc::nest nt;