@@ -15,197 +15,183 @@ namespace xt::comparison
1515{
1616
1717 // ========================================================================
18- // Vector Addition: z = x + y
18+ // Helpers
1919 // ========================================================================
2020
21- // Raw C++ implementation with std::vector
22- static void add_vector_raw_cpp (benchmark::State& state)
21+ // Benchmark range configuration
22+ constexpr std::size_t min_size = 8 ;
23+ constexpr std::size_t max_size = 16384 ;
24+ constexpr std::size_t multiplier = 4 ;
25+
26+ // Helper to create xtensor vectors
27+ inline auto make_xtensor (std::size_t size, double val)
2328 {
24- using value_type = double ;
25- using size_type = std::size_t ;
26-
27- const size_type size = state.range (0 );
28- std::vector<value_type> x (size, 1.0 );
29- std::vector<value_type> y (size, 2.0 );
30- std::vector<value_type> z (size);
31-
32- for (auto _ : state)
33- {
34- for (size_type i = 0 ; i < size; ++i)
35- {
36- z[i] = x[i] + y[i];
37- }
38- benchmark::DoNotOptimize (z.data ());
39- }
29+ return xt::xtensor<double , 1 >::from_shape ({size}) * val;
4030 }
4131
42- // xtensor implementation with xarray
43- static void add_vector_xtensor_xarray (benchmark::State& state)
32+ inline auto make_xtensor_zeros (std::size_t size)
4433 {
45- using size_type = std::size_t ;
34+ auto c = xt::xtensor<double , 1 >::from_shape ({size});
35+ c.fill (0 );
36+ return c;
37+ }
4638
47- const size_type size = state.range (0 );
48- xarray<double > x = xt::ones<double >({size});
49- xarray<double > y = 2.0 * xt::ones<double >({size});
50- xarray<double > z;
39+ // Helper to create xarray
40+ inline auto make_xarray (std::size_t size, double val)
41+ {
42+ return xt::xarray<double >::from_shape ({size}) * val;
43+ }
5144
52- for (auto _ : state)
53- {
54- z = x + y;
55- benchmark::DoNotOptimize (z.data ());
45+ // Macro for benchmark loop (reduces boilerplate)
46+ #define BENCHMARK_LOOP (state, container, ...) \
47+ for (auto _ : state) { \
48+ __VA_ARGS__; \
49+ benchmark::DoNotOptimize (container.data ()); \
5650 }
57- }
5851
59- // xtensor implementation with xtensor (fixed size)
60- static void add_vector_xtensor_xtensor (benchmark::State& state)
52+ // Macro for registering benchmarks with standard sizes
53+ #define REGISTER_BENCHMARK (func ) \
54+ BENCHMARK (func)->Range (min_size, max_size)->RangeMultiplier(multiplier)
55+
56+ // ========================================================================
57+ // Vector Addition: z = x + y
58+ // ========================================================================
59+
60+ static void add_vector_std(benchmark::State& state)
6161 {
62- using size_type = std::size_t ;
62+ const std::size_t size = state.range (0 );
63+ std::vector<double > x (size, 1.0 );
64+ std::vector<double > y (size, 2.0 );
65+ std::vector<double > z (size);
66+
67+ BENCHMARK_LOOP (state, z,
68+ for (std::size_t i = 0 ; i < size; ++i)
69+ z[i] = x[i] + y[i];
70+ );
71+ }
6372
64- const size_type size = state.range (0 );
65- xtensor<double , 1 > x = xt::ones<double >({size});
66- xtensor<double , 1 > y = 2.0 * xt::ones<double >({size});
67- xtensor<double , 1 > z;
73+ static void add_vector_xarray (benchmark::State& state)
74+ {
75+ const std::size_t size = state.range (0 );
76+ auto x = make_xarray (size, 1.0 );
77+ auto y = make_xarray (size, 2.0 );
78+ xt::xarray<double > z;
6879
69- for (auto _ : state)
70- {
80+ BENCHMARK_LOOP (state, z,
7181 z = x + y;
72- benchmark::DoNotOptimize (z.data ());
73- }
82+ );
7483 }
7584
76- // xtensor with noalias (avoids temporary allocation)
77- static void add_vector_xtensor_noalias (benchmark::State& state)
85+ static void add_vector_xtensor (benchmark::State& state)
7886 {
79- using size_type = std::size_t ;
87+ const std::size_t size = state.range (0 );
88+ auto x = make_xtensor (size, 1.0 );
89+ auto y = make_xtensor (size, 2.0 );
90+ xt::xtensor<double , 1 > z;
8091
81- const size_type size = state. range ( 0 );
82- xtensor< double , 1 > x = xt::ones< double >({size}) ;
83- xtensor< double , 1 > y = 2.0 * xt::ones< double >({size} );
84- xtensor< double , 1 > z = xt::zeros< double >({size});
92+ BENCHMARK_LOOP (state, z,
93+ z = x + y ;
94+ );
95+ }
8596
86- for (auto _ : state)
87- {
97+ static void add_vector_noalias (benchmark::State& state)
98+ {
99+ const std::size_t size = state.range (0 );
100+ auto x = make_xtensor (size, 1.0 );
101+ auto y = make_xtensor (size, 2.0 );
102+ auto z = make_xtensor_zeros (size);
103+
104+ BENCHMARK_LOOP (state, z,
88105 xt::noalias (z) = x + y;
89- benchmark::DoNotOptimize (z.data ());
90- }
106+ );
91107 }
92108
93109 // ========================================================================
94- // Scalar Addition: z = x + a (add_scalar)
110+ // Scalar Addition: z = x + a
95111 // ========================================================================
96112
97- // Raw C++
98- static void add_scalar_raw_cpp (benchmark::State& state)
113+ static void add_scalar_std (benchmark::State& state)
99114 {
100- using value_type = double ;
101- using size_type = std::size_t ;
102-
103- const size_type size = state.range (0 );
104- const value_type a = 5.0 ;
105- std::vector<value_type> x (size, 1.0 );
106- std::vector<value_type> z (size);
107-
108- for (auto _ : state)
109- {
110- for (size_type i = 0 ; i < size; ++i)
111- {
115+ const std::size_t size = state.range (0 );
116+ constexpr double a = 5.0 ;
117+ std::vector<double > x (size, 1.0 );
118+ std::vector<double > z (size);
119+
120+ BENCHMARK_LOOP (state, z,
121+ for (std::size_t i = 0 ; i < size; ++i)
112122 z[i] = x[i] + a;
113- }
114- benchmark::DoNotOptimize (z.data ());
115- }
123+ );
116124 }
117125
118- // xtensor
119126 static void add_scalar_xtensor (benchmark::State& state)
120127 {
121- using size_type = std::size_t ;
128+ const std::size_t size = state.range (0 );
129+ constexpr double a = 5.0 ;
130+ auto x = make_xtensor (size, 1.0 );
131+ xt::xtensor<double , 1 > z;
122132
123- const size_type size = state.range (0 );
124- const double a = 5.0 ;
125- xtensor<double , 1 > x = xt::ones<double >({size});
126- xtensor<double , 1 > z;
127-
128- for (auto _ : state)
129- {
133+ BENCHMARK_LOOP (state, z,
130134 z = x + a;
131- benchmark::DoNotOptimize (z.data ());
132- }
135+ );
133136 }
134137
135- // xtensor with noalias
136- static void add_scalar_xtensor_noalias (benchmark::State& state)
138+ static void add_scalar_noalias (benchmark::State& state)
137139 {
138- using size_type = std::size_t ;
140+ const std::size_t size = state.range (0 );
141+ constexpr double a = 5.0 ;
142+ auto x = make_xtensor (size, 1.0 );
143+ auto z = make_xtensor_zeros (size);
139144
140- const size_type size = state.range (0 );
141- const double a = 5.0 ;
142- xtensor<double , 1 > x = xt::ones<double >({size});
143- xtensor<double , 1 > z = xt::zeros<double >({size});
144-
145- for (auto _ : state)
146- {
145+ BENCHMARK_LOOP (state, z,
147146 xt::noalias (z) = x + a;
148- benchmark::DoNotOptimize (z.data ());
149- }
147+ );
150148 }
151149
152150 // ========================================================================
153151 // Scalar Multiplication: y = a * x
154152 // ========================================================================
155153
156- // Raw C++
157- static void mul_scalar_raw_cpp (benchmark::State& state)
154+ static void mul_scalar_std (benchmark::State& state)
158155 {
159- using value_type = double ;
160- using size_type = std::size_t ;
161-
162- const size_type size = state.range (0 );
163- const value_type a = 2.5 ;
164- std::vector<value_type> x (size, 1.0 );
165- std::vector<value_type> y (size);
166-
167- for (auto _ : state)
168- {
169- for (size_type i = 0 ; i < size; ++i)
170- {
156+ const std::size_t size = state.range (0 );
157+ constexpr double a = 2.5 ;
158+ std::vector<double > x (size, 1.0 );
159+ std::vector<double > y (size);
160+
161+ BENCHMARK_LOOP (state, y,
162+ for (std::size_t i = 0 ; i < size; ++i)
171163 y[i] = a * x[i];
172- }
173- benchmark::DoNotOptimize (y.data ());
174- }
164+ );
175165 }
176166
177- // xtensor
178167 static void mul_scalar_xtensor (benchmark::State& state)
179168 {
180- using size_type = std::size_t ;
169+ const std::size_t size = state.range (0 );
170+ constexpr double a = 2.5 ;
171+ auto x = make_xtensor (size, 1.0 );
172+ xt::xtensor<double , 1 > y;
181173
182- const size_type size = state.range (0 );
183- const double a = 2.5 ;
184- xtensor<double , 1 > x = xt::ones<double >({size});
185- xtensor<double , 1 > y;
186-
187- for (auto _ : state)
188- {
174+ BENCHMARK_LOOP (state, y,
189175 y = a * x;
190- benchmark::DoNotOptimize (y.data ());
191- }
176+ );
192177 }
193178
194179 // ========================================================================
195- // Register benchmarks with different sizes
180+ // Register benchmarks
196181 // ========================================================================
197182
198- // Vector sizes to test: 64, 256, 1024, 4096, 16384
199- BENCHMARK (add_vector_raw_cpp)-> Range ( 64 , 16384 )->RangeMultiplier( 4 );
200- BENCHMARK (add_vector_xtensor_xarray)-> Range ( 64 , 16384 )->RangeMultiplier( 4 );
201- BENCHMARK (add_vector_xtensor_xtensor)-> Range ( 64 , 16384 )->RangeMultiplier( 4 );
202- BENCHMARK (add_vector_xtensor_noalias)-> Range ( 64 , 16384 )->RangeMultiplier( 4 );
183+ // Vector + Vector
184+ REGISTER_BENCHMARK (add_vector_std );
185+ REGISTER_BENCHMARK (add_vector_xarray );
186+ REGISTER_BENCHMARK (add_vector_xtensor );
187+ REGISTER_BENCHMARK (add_vector_noalias );
203188
204- BENCHMARK (add_scalar_raw_cpp)->Range (64 , 16384 )->RangeMultiplier(4 );
205- BENCHMARK (add_scalar_xtensor)->Range (64 , 16384 )->RangeMultiplier(4 );
206- BENCHMARK (add_scalar_xtensor_noalias)->Range (64 , 16384 )->RangeMultiplier(4 );
189+ // Scalar operations
190+ REGISTER_BENCHMARK (add_scalar_std);
191+ REGISTER_BENCHMARK (add_scalar_xtensor);
192+ REGISTER_BENCHMARK (add_scalar_noalias);
207193
208- BENCHMARK (mul_scalar_raw_cpp)-> Range ( 64 , 16384 )->RangeMultiplier( 4 );
209- BENCHMARK (mul_scalar_xtensor)-> Range ( 64 , 16384 )->RangeMultiplier( 4 );
194+ REGISTER_BENCHMARK (mul_scalar_std );
195+ REGISTER_BENCHMARK (mul_scalar_xtensor);
210196
211197}
0 commit comments