• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
8 #if defined(ONLY_V2)
9 # define NO_BV
10 # define NO_SV
11 #endif
12 
13 #if defined(ONLY_BV)
14 # define NO_V2
15 # define NO_SV
16 #endif
17 
18 #if defined(ONLY_SV)
19 # define NO_V2
20 # define NO_BV
21 #endif
22 
23 #if !defined(NO_V2)
24 #include <boost/variant2/variant.hpp>
25 #endif
26 
27 #if !defined(NO_BV)
28 #include <boost/variant.hpp>
29 #endif
30 
31 #if !defined(NO_SV)
32 #include <variant>
33 #endif
34 
35 #include <type_traits>
36 #include <chrono>
37 #include <iostream>
38 #include <iomanip>
39 #include <vector>
40 
41 struct prefix
42 {
43     int v_;
44 };
45 
46 struct X1: prefix {};
47 struct X2: prefix {};
48 struct X3: prefix {};
49 struct X4: prefix {};
50 struct X5: prefix {};
51 struct X6: prefix {};
52 struct X7: prefix {};
53 struct X8: prefix {};
54 struct X9: prefix {};
55 struct X10: prefix {};
56 struct X11: prefix {};
57 struct X12: prefix {};
58 
get_value(prefix const & v)59 inline int get_value( prefix const& v )
60 {
61     return v.v_;
62 }
63 
64 #if !defined(NO_V2)
65 
get_value(boost::variant2::variant<T...> const & v)66 template<class... T> int get_value( boost::variant2::variant<T...> const& v )
67 {
68     return visit( []( prefix const& x ) { return x.v_; }, v );
69 }
70 
71 #endif
72 
73 #if !defined(NO_BV)
74 
get_value(boost::variant<T...> const & v)75 template<class... T> int get_value( boost::variant<T...> const& v )
76 {
77     return boost::apply_visitor( []( prefix const& x ) { return x.v_; }, v );
78 }
79 
80 #endif
81 
82 #if !defined(NO_SV)
83 
get_value(std::variant<T...> const & v)84 template<class... T> int get_value( std::variant<T...> const& v )
85 {
86     return visit( []( prefix const& x ) { return x.v_; }, v );
87 }
88 
89 #endif
90 
test_(int N)91 template<class V> void test_( int N )
92 {
93     std::vector<V> w;
94     // lack of reserve is deliberate
95 
96     auto tp1 = std::chrono::high_resolution_clock::now();
97 
98     for( int i = 0; i < N / 12; ++i )
99     {
100         w.push_back( X1{ i } );
101         w.push_back( X2{ i } );
102         w.push_back( X3{ i } );
103         w.push_back( X4{ i } );
104         w.push_back( X5{ i } );
105         w.push_back( X6{ i } );
106         w.push_back( X7{ i } );
107         w.push_back( X8{ i } );
108         w.push_back( X9{ i } );
109         w.push_back( X10{ i } );
110         w.push_back( X11{ i } );
111         w.push_back( X12{ i } );
112     }
113 
114     unsigned long long s = 0;
115 
116     for( std::size_t i = 0, n = w.size(); i < n; ++i )
117     {
118         s = s + get_value( w[ i ] );
119     }
120 
121     auto tp2 = std::chrono::high_resolution_clock::now();
122 
123     std::cout << std::setw( 6 ) << std::chrono::duration_cast<std::chrono::milliseconds>( tp2 - tp1 ).count() << " ms; S=" << s << "\n";
124 }
125 
test(int N)126 template<class... T> void test( int N )
127 {
128     std::cout << "N=" << N << ":\n";
129 
130     std::cout << "        prefix: "; test_<prefix>( N );
131 #if !defined(NO_V2)
132     std::cout << "      variant2: "; test_<boost::variant2::variant<T...>>( N );
133 #endif
134 #if !defined(NO_BV)
135     std::cout << "boost::variant: "; test_<boost::variant<T...>>( N );
136 #endif
137 #if !defined(NO_SV)
138     std::cout << "  std::variant: "; test_<std::variant<T...>>( N );
139 #endif
140 
141     std::cout << '\n';
142 }
143 
main()144 int main()
145 {
146     int const N = 100'000'000;
147 
148     test<X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12>( N );
149 }
150