benchmark2.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright 2019 Peter Dimov
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. //
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. #if defined(ONLY_V2)
  8. # define NO_BV
  9. # define NO_SV
  10. #endif
  11. #if defined(ONLY_BV)
  12. # define NO_V2
  13. # define NO_SV
  14. #endif
  15. #if defined(ONLY_SV)
  16. # define NO_V2
  17. # define NO_BV
  18. #endif
  19. #if !defined(NO_V2)
  20. #include <boost/variant2/variant.hpp>
  21. #endif
  22. #if !defined(NO_BV)
  23. #include <boost/variant.hpp>
  24. #endif
  25. #if !defined(NO_SV)
  26. #include <variant>
  27. #endif
  28. #include <type_traits>
  29. #include <chrono>
  30. #include <iostream>
  31. #include <iomanip>
  32. #include <vector>
  33. struct prefix
  34. {
  35. int v_;
  36. };
  37. struct X1: prefix {};
  38. struct X2: prefix {};
  39. struct X3: prefix {};
  40. struct X4: prefix {};
  41. struct X5: prefix {};
  42. struct X6: prefix {};
  43. struct X7: prefix {};
  44. struct X8: prefix {};
  45. struct X9: prefix {};
  46. struct X10: prefix {};
  47. struct X11: prefix {};
  48. struct X12: prefix {};
  49. inline int get_value( prefix const& v )
  50. {
  51. return v.v_;
  52. }
  53. #if !defined(NO_V2)
  54. template<class... T> int get_value( boost::variant2::variant<T...> const& v )
  55. {
  56. return visit( []( prefix const& x ) { return x.v_; }, v );
  57. }
  58. #endif
  59. #if !defined(NO_BV)
  60. template<class... T> int get_value( boost::variant<T...> const& v )
  61. {
  62. return boost::apply_visitor( []( prefix const& x ) { return x.v_; }, v );
  63. }
  64. #endif
  65. #if !defined(NO_SV)
  66. template<class... T> int get_value( std::variant<T...> const& v )
  67. {
  68. return visit( []( prefix const& x ) { return x.v_; }, v );
  69. }
  70. #endif
  71. template<class V> void test_( int N )
  72. {
  73. std::vector<V> w;
  74. // lack of reserve is deliberate
  75. auto tp1 = std::chrono::high_resolution_clock::now();
  76. for( int i = 0; i < N / 12; ++i )
  77. {
  78. w.push_back( X1{ i } );
  79. w.push_back( X2{ i } );
  80. w.push_back( X3{ i } );
  81. w.push_back( X4{ i } );
  82. w.push_back( X5{ i } );
  83. w.push_back( X6{ i } );
  84. w.push_back( X7{ i } );
  85. w.push_back( X8{ i } );
  86. w.push_back( X9{ i } );
  87. w.push_back( X10{ i } );
  88. w.push_back( X11{ i } );
  89. w.push_back( X12{ i } );
  90. }
  91. unsigned long long s = 0;
  92. for( std::size_t i = 0, n = w.size(); i < n; ++i )
  93. {
  94. s = s + get_value( w[ i ] );
  95. }
  96. auto tp2 = std::chrono::high_resolution_clock::now();
  97. std::cout << std::setw( 6 ) << std::chrono::duration_cast<std::chrono::milliseconds>( tp2 - tp1 ).count() << " ms; S=" << s << "\n";
  98. }
  99. template<class... T> void test( int N )
  100. {
  101. std::cout << "N=" << N << ":\n";
  102. std::cout << " prefix: "; test_<prefix>( N );
  103. #if !defined(NO_V2)
  104. std::cout << " variant2: "; test_<boost::variant2::variant<T...>>( N );
  105. #endif
  106. #if !defined(NO_BV)
  107. std::cout << "boost::variant: "; test_<boost::variant<T...>>( N );
  108. #endif
  109. #if !defined(NO_SV)
  110. std::cout << " std::variant: "; test_<std::variant<T...>>( N );
  111. #endif
  112. std::cout << '\n';
  113. }
  114. int main()
  115. {
  116. int const N = 100'000'000;
  117. test<X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12>( N );
  118. }