move_perf.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. // (C) Copyright Antony Polukhin 2012-2014.
  2. // Use, modification and distribution are subject to the
  3. // Boost Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. // See http://www.boost.org/libs/config for most recent version.
  6. //
  7. // Testing variant performance rvalue copy/assign performance
  8. //
  9. #define BOOST_ERROR_CODE_HEADER_ONLY
  10. #define BOOST_CHRONO_HEADER_ONLY
  11. #include <boost/chrono.hpp>
  12. #include <boost/variant.hpp>
  13. #include <string>
  14. #include <vector>
  15. struct scope {
  16. typedef boost::chrono::steady_clock test_clock;
  17. typedef boost::chrono::milliseconds duration_t;
  18. test_clock::time_point start_;
  19. const char* const message_;
  20. explicit scope(const char* const message)
  21. : start_(test_clock::now())
  22. , message_(message)
  23. {}
  24. ~scope() {
  25. std::cout << message_ << " " << boost::chrono::duration_cast<duration_t>(test_clock::now() - start_) << std::endl;
  26. }
  27. };
  28. static void do_test(bool do_count_cleanup_time = false) {
  29. BOOST_STATIC_CONSTANT(std::size_t, c_run_count = 5000000);
  30. typedef std::vector<char> str_t;
  31. typedef boost::variant<int, str_t, float> var_t;
  32. const char hello1_c[] = "hello long word";
  33. const str_t hello1(hello1_c, hello1_c + sizeof(hello1_c));
  34. const char hello2_c[] = "Helllloooooooooooooooooooooooooooooooo!!!!!!!!!!!!!";
  35. const str_t hello2(hello2_c, hello2_c + sizeof(hello2_c));
  36. if (do_count_cleanup_time) {
  37. std::cout << "#############################################\n";
  38. std::cout << "#############################################\n";
  39. std::cout << "NOW TIMES WITH DATA DESTRUCTION\n";
  40. std::cout << "#############################################\n";
  41. }
  42. std::vector<var_t> data_from, data_to;
  43. data_from.resize(c_run_count, hello1);
  44. data_to.reserve(c_run_count);
  45. {
  46. scope sc("boost::variant(const variant&) copying speed");
  47. for (std::size_t i = 0; i < c_run_count; ++i) {
  48. data_to.push_back(data_from[i]);
  49. }
  50. if (do_count_cleanup_time) {
  51. data_to.clear();
  52. data_from.clear();
  53. }
  54. }
  55. data_from.resize(c_run_count, hello1);
  56. data_to.clear();
  57. data_to.reserve(c_run_count);
  58. {
  59. scope sc("boost::variant(variant&&) moving speed");
  60. for (std::size_t i = 0; i < c_run_count; ++i) {
  61. data_to.push_back(boost::move(data_from[i]));
  62. }
  63. if (do_count_cleanup_time) {
  64. data_to.clear();
  65. data_from.clear();
  66. }
  67. }
  68. std::cout << "#############################################\n";
  69. data_from.clear();
  70. data_from.resize(c_run_count, hello2);
  71. data_to.clear();
  72. data_to.resize(c_run_count, hello2);
  73. {
  74. scope sc("boost::variant=(const variant&) copying speed on same types");
  75. for (std::size_t i = 0; i < c_run_count; ++i) {
  76. data_to[i] = data_from[i];
  77. }
  78. if (do_count_cleanup_time) {
  79. data_to.clear();
  80. data_from.clear();
  81. }
  82. }
  83. data_from.resize(c_run_count, hello2);
  84. data_to.clear();
  85. data_to.resize(c_run_count, hello2);
  86. {
  87. scope sc("boost::variant=(variant&&) moving speed on same types");
  88. for (std::size_t i = 0; i < c_run_count; ++i) {
  89. data_to[i] = boost::move(data_from[i]);
  90. }
  91. if (do_count_cleanup_time) {
  92. data_to.clear();
  93. data_from.clear();
  94. }
  95. }
  96. std::cout << "#############################################\n";
  97. data_from.clear();
  98. data_from.resize(c_run_count, hello2);
  99. data_to.clear();
  100. data_to.resize(c_run_count, var_t(0));
  101. {
  102. scope sc("boost::variant=(const variant&) copying speed on different types");
  103. for (std::size_t i = 0; i < c_run_count; ++i) {
  104. data_to[i] = data_from[i];
  105. }
  106. if (do_count_cleanup_time) {
  107. data_to.clear();
  108. data_from.clear();
  109. }
  110. }
  111. data_from.resize(c_run_count, hello2);
  112. data_to.clear();
  113. data_to.resize(c_run_count, var_t(0));
  114. {
  115. scope sc("boost::variant=(variant&&) moving speed on different types");
  116. for (std::size_t i = 0; i < c_run_count; ++i) {
  117. data_to[i] = boost::move(data_from[i]);
  118. }
  119. if (do_count_cleanup_time) {
  120. data_to.clear();
  121. data_from.clear();
  122. }
  123. }
  124. std::cout << "#############################################\n";
  125. data_from.clear();
  126. data_from.resize(c_run_count, var_t(0));
  127. data_to.clear();
  128. data_to.resize(c_run_count, hello2);
  129. {
  130. scope sc("boost::variant=(const variant&) copying speed on different types II");
  131. for (std::size_t i = 0; i < c_run_count; ++i) {
  132. data_to[i] = data_from[i];
  133. }
  134. if (do_count_cleanup_time) {
  135. data_to.clear();
  136. data_from.clear();
  137. }
  138. }
  139. data_from.resize(c_run_count, var_t(0));
  140. data_to.clear();
  141. data_to.resize(c_run_count, hello2);
  142. {
  143. scope sc("boost::variant=(variant&&) moving speed on different types II");
  144. for (std::size_t i = 0; i < c_run_count; ++i) {
  145. data_to[i] = boost::move(data_from[i]);
  146. }
  147. if (do_count_cleanup_time) {
  148. data_to.clear();
  149. data_from.clear();
  150. }
  151. }
  152. std::cout << "#############################################\n";
  153. std::vector<str_t> s1(c_run_count, hello2);
  154. data_to.clear();
  155. data_to.resize(c_run_count, var_t(0));
  156. {
  157. scope sc("boost::variant=(const T&) copying speed");
  158. for (std::size_t i = 0; i < c_run_count; ++i) {
  159. data_to[i] = s1[i];
  160. }
  161. if (do_count_cleanup_time) {
  162. data_to.clear();
  163. s1.clear();
  164. }
  165. }
  166. std::vector<str_t> s2(c_run_count, hello2);
  167. data_to.clear();
  168. data_to.resize(c_run_count, var_t(0));
  169. {
  170. scope sc("boost::variant=(T&&) moving speed");
  171. for (std::size_t i = 0; i < c_run_count; ++i) {
  172. data_to[i] = boost::move(s2[i]);
  173. }
  174. if (do_count_cleanup_time) {
  175. data_to.clear();
  176. s2.clear();
  177. }
  178. }
  179. }
  180. int main () {
  181. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  182. std::cout << "# Running tests in C++11 mode (with rvalues).\n";
  183. #else
  184. std::cout << "# Running tests in C++03 mode (without rvalues).\n";
  185. #endif
  186. do_test(false);
  187. do_test(true);
  188. }