zip_efficiency.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #include "measure.hpp"
  7. //~ #define FUSION_MAX_VECTOR_SIZE 30
  8. #include <boost/fusion/algorithm/iteration/accumulate.hpp>
  9. #include <boost/fusion/algorithm/transformation/zip.hpp>
  10. #include <boost/fusion/container/vector.hpp>
  11. #include <boost/fusion/sequence/intrinsic/value_at.hpp>
  12. #include <boost/fusion/sequence/intrinsic/at.hpp>
  13. #include <boost/type_traits/remove_reference.hpp>
  14. #include <iostream>
  15. #ifdef _MSC_VER
  16. // inline aggressively
  17. # pragma inline_recursion(on) // turn on inline recursion
  18. # pragma inline_depth(255) // max inline depth
  19. #endif
  20. namespace
  21. {
  22. struct zip_add
  23. {
  24. template<typename Lhs, typename Rhs>
  25. struct result
  26. {
  27. typedef typename
  28. boost::remove_reference<
  29. typename boost::fusion::result_of::value_at_c<Lhs, 0>::type
  30. >::type
  31. type;
  32. };
  33. template<typename Lhs, typename Rhs>
  34. typename result<Lhs, Rhs>::type
  35. operator()(const Lhs& lhs, const Rhs& rhs) const
  36. {
  37. return boost::fusion::at_c<0>(lhs) + boost::fusion::at_c<1>(lhs) + rhs;
  38. }
  39. };
  40. // Our Accumulator function
  41. template <typename T>
  42. struct zip_accumulator
  43. {
  44. zip_accumulator()
  45. : sum()
  46. {}
  47. template <typename Sequence>
  48. void operator()(Sequence const& seq)
  49. {
  50. this->sum += boost::fusion::accumulate(seq, 0, zip_add());
  51. }
  52. T sum;
  53. };
  54. template <typename T>
  55. void check(T const& seq, char const* info)
  56. {
  57. test::measure<zip_accumulator<int> >(seq, 1);
  58. std::cout << info << test::live_code << std::endl;
  59. }
  60. template <typename T>
  61. void measure(T const& seq, char const* info, long const repeats)
  62. {
  63. std::cout
  64. << info
  65. << test::measure<zip_accumulator<int> >(seq, repeats)
  66. << std::endl;
  67. }
  68. }
  69. int main()
  70. {
  71. using namespace boost::fusion;
  72. std::cout.setf(std::ios::scientific);
  73. vector<
  74. int, int, int
  75. >
  76. vsmall_1(BOOST_PP_ENUM_PARAMS(3,));
  77. vector<
  78. int, int, int
  79. >
  80. vsmall_2(BOOST_PP_ENUM_PARAMS(3,));
  81. vector<
  82. int, int, int, int, int, int, int, int, int, int
  83. >
  84. vmedium_1(BOOST_PP_ENUM_PARAMS(10,));
  85. vector<
  86. int, int, int, int, int, int, int, int, int, int
  87. >
  88. vmedium_2(BOOST_PP_ENUM_PARAMS(10,));
  89. //~ vector<
  90. //~ int, int, int, int, int, int, int, int, int, int
  91. //~ , int, int, int, int, int, int, int, int, int, int
  92. //~ , int, int, int, int, int, int, int, int, int, int
  93. //~ >
  94. //~ vbig_1(BOOST_PP_ENUM_PARAMS(30,));
  95. //~ vector<
  96. //~ int, int, int, int, int, int, int, int, int, int
  97. //~ , int, int, int, int, int, int, int, int, int, int
  98. //~ , int, int, int, int, int, int, int, int, int, int
  99. //~ >
  100. //~ vbig_2(BOOST_PP_ENUM_PARAMS(30,));
  101. // first decide how many repetitions to measure
  102. long repeats = 100;
  103. double measured = 0;
  104. while (measured < 2.0 && repeats <= 10000000)
  105. {
  106. repeats *= 10;
  107. boost::timer time;
  108. test::hammer<zip_accumulator<int> >(zip(vsmall_1, vsmall_2), repeats);
  109. test::hammer<zip_accumulator<int> >(zip(vmedium_1, vmedium_2), repeats);
  110. //~ test::hammer<zip_accumulator<int> >(zip(vbig_1, vbig_2), repeats);
  111. measured = time.elapsed();
  112. }
  113. check(zip(vsmall_1, vsmall_2),
  114. "small zip accumulated result: ");
  115. check(zip(vmedium_1, vmedium_2),
  116. "medium zip accumulated result: ");
  117. //~ check(zip(vbig_1, vbig_2),
  118. //~ "big zip accumulated result: ");
  119. measure(zip(vsmall_1, vsmall_2),
  120. "small zip time: ", repeats);
  121. measure(zip(vmedium_1, vmedium_2),
  122. "medium zip time: ", repeats);
  123. //~ measure(zip(vbig_1, vbig_2),
  124. //~ "big zip time: ", repeats);
  125. // This is ultimately responsible for preventing all the test code
  126. // from being optimized away. Change this to return 0 and you
  127. // unplug the whole test's life support system.
  128. return test::live_code != 0;
  129. }