1// -*- C++ -*- 2 3// Copyright (C) 2005, 2006, 2009 Free Software Foundation, Inc. 4// 5// This file is part of the GNU ISO C++ Library. This library is free 6// software; you can redistribute it and/or modify it under the terms 7// of the GNU General Public License as published by the Free Software 8// Foundation; either version 3, or (at your option) any later 9// version. 10 11// This library is distributed in the hope that it will be useful, but 12// WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14// General Public License for more details. 15 16// You should have received a copy of the GNU General Public License 17// along with this library; see the file COPYING3. If not see 18// <http://www.gnu.org/licenses/>. 19 20 21// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. 22 23// Permission to use, copy, modify, sell, and distribute this software 24// is hereby granted without fee, provided that the above copyright 25// notice appears in all copies, and that both that copyright notice 26// and this permission notice appear in supporting documentation. None 27// of the above authors, nor IBM Haifa Research Laboratories, make any 28// representation about the suitability of this software for any 29// purpose. It is provided "as is" without express or implied 30// warranty. 31 32/** 33 * @file join_test.hpp 34 * Contains a join performance test. 35 */ 36 37#ifndef PB_DS_JOIN_TEST_HPP 38#define PB_DS_JOIN_TEST_HPP 39 40#include <performance/time/timing_test_base.hpp> 41#include <ext/pb_ds/detail/type_utils.hpp> 42#include <performance/io/xml_formatter.hpp> 43#include <common_type/priority_queue/string_form.hpp> 44#include <iterator> 45 46namespace __gnu_pbds 47{ 48 namespace test 49 { 50 namespace detail 51 { 52 template<typename It, typename Cntnr> 53 class double_push_functor 54 { 55 const It _M_begin; 56 const It _M_end; 57 58 public: 59 double_push_functor(It b, It e) : _M_begin(b), _M_end(e) { } 60 61 void 62 operator()(std::size_t resolution) 63 { 64 typedef typename Cntnr::const_reference const_reference; 65 for (std::size_t n = 0; n < resolution; ++n) 66 { 67 Cntnr c0; 68 Cntnr c1; 69 for (It it = _M_begin; it != _M_end; ++it) 70 { 71 c0.push(const_reference(it->first)); 72 c1.push(const_reference(it->first)); 73 } 74 } 75 } 76 }; 77 78 template<typename It, typename Cntnr> 79 class double_push_join_functor 80 { 81 const It _M_begin; 82 const It _M_end; 83 84 public: 85 double_push_join_functor(It b, It e) : _M_begin(b), _M_end(e) { } 86 87 void 88 operator()(std::size_t resolution) 89 { 90 typedef typename Cntnr::const_reference const_reference; 91 for (std::size_t n = 0; n < resolution; ++n) 92 { 93 Cntnr c0; 94 Cntnr c1; 95 for (It it = _M_begin; it != _M_end; ++it) 96 { 97 c0.push(const_reference(it->first)); 98 c1.push(const_reference(it->first)); 99 } 100 c0.join(c1); 101 } 102 } 103 }; 104 } // namespace detail 105 106 template<typename It> 107 class join_test : private __gnu_pbds::test::detail::timing_test_base 108 { 109 public: 110 join_test(It ins_b, size_t ins_vn, size_t ins_vs, size_t ins_vm) 111 : m_ins_b(ins_b), m_ins_vn(ins_vn), m_ins_vs(ins_vs), m_ins_vm(ins_vm) 112 { } 113 114 template<typename Cntnr> 115 void 116 operator()(Cntnr) 117 { 118 using __gnu_pbds::test::detail::double_push_functor; 119 using __gnu_pbds::test::detail::double_push_join_functor; 120 typedef __gnu_pbds::test::detail::timing_test_base base_type; 121 typedef double_push_functor<It, Cntnr> psh_fnct; 122 typedef double_push_join_functor<It, Cntnr> psh_jn_fnct; 123 124 typedef xml_result_set_performance_formatter formatter_type; 125 formatter_type res(string_form<Cntnr>::name(), 126 string_form<Cntnr>::desc()); 127 128 for (size_t n = 0; m_ins_vn + n* m_ins_vs < m_ins_vm; ++n) 129 { 130 const size_t v = m_ins_vn + n * m_ins_vs; 131 It b = m_ins_b; 132 It e = m_ins_b; 133 std::advance(e, v); 134 135 psh_fnct double_push_fn(b, e); 136 const double dbl_psh_res = base_type::operator()(double_push_fn); 137 psh_jn_fnct dbl_psh_jn_fn(b, e); 138 const double dbl_psh_jn_res = base_type::operator()(dbl_psh_jn_fn); 139 const double min_res = double(timing_test_base::min_time_res()); 140 const double effective_delta = std::max(dbl_psh_jn_res - dbl_psh_res, min_res); 141 res.add_res(v, effective_delta / v); 142 } 143 } 144 145 private: 146 join_test(const join_test&); 147 148 template<typename Cntnr> 149 void 150 join(Cntnr, It b, It e) 151 { 152 Cntnr cntnr; 153 typedef typename Cntnr::const_reference const_reference; 154 for (It it = b; it != e; ++it) 155 cntnr.join(const_reference(*it)); 156 } 157 158 const It m_ins_b; 159 const size_t m_ins_vn; 160 const size_t m_ins_vs; 161 const size_t m_ins_vm; 162 }; 163 } // namespace test 164} // namespace __gnu_pbds 165 166#endif 167 168