From 954922408aa4401edbd73ff045e097a672b104f1 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Wed, 7 Jan 2026 23:33:18 +0100 Subject: [PATCH 1/6] Add comparison benchmarks: xtensor vs raw C++ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add optional comparison benchmarks that directly compare xtensor performance against raw C++ implementations. This helps users understand the performance characteristics and overhead of xtensor. Changes: - Add XTENSOR_BUILD_COMPARISON_BENCHMARKS CMake option (OFF by default) - Add benchmark/comparison/ directory with BLAS1 comparisons - add_vector: z = x + y (vector + vector) - add_scalar: z = x + a (vector + scalar) - mul_scalar: y = a * x (scalar * vector) - Each benchmark compares raw C++ vs xtensor (xarray, xtensor, noalias) Usage: cmake .. -DXTENSOR_BUILD_COMPARISON_BENCHMARKS=ON make benchmark_comparison ./comparison/benchmark_comparison 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- benchmark/CMakeLists.txt | 7 + benchmark/comparison/CMakeLists.txt | 16 ++ benchmark/comparison/blas1_comparison.cpp | 211 ++++++++++++++++++++++ benchmark/comparison/comparison_main.cpp | 20 ++ 4 files changed, 254 insertions(+) create mode 100644 benchmark/comparison/CMakeLists.txt create mode 100644 benchmark/comparison/blas1_comparison.cpp create mode 100644 benchmark/comparison/comparison_main.cpp diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 9928eb155..24071a043 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -144,3 +144,10 @@ add_custom_target(xpowerbench COMMAND benchmark_xtensor --benchmark_out=results.csv --benchmark_out_format=csv COMMAND sudo cpupower frequency-set --governor powersave DEPENDS ${XTENSOR_BENCHMARK_TARGET}) + +# Comparison benchmarks (xtensor vs raw C++) +option(XTENSOR_BUILD_COMPARISON_BENCHMARKS "Build comparison benchmarks vs raw C++" OFF) + +if(XTENSOR_BUILD_COMPARISON_BENCHMARKS) + add_subdirectory(comparison) +endif() diff --git a/benchmark/comparison/CMakeLists.txt b/benchmark/comparison/CMakeLists.txt new file mode 100644 index 000000000..7472de0b6 --- /dev/null +++ b/benchmark/comparison/CMakeLists.txt @@ -0,0 +1,16 @@ +############################################################################ +# Comparison benchmarks: xtensor vs raw C++ +############################################################################ + +set(COMPARISON_BENCHMARK + blas1_comparison.cpp + comparison_main.cpp +) + +add_executable(benchmark_comparison ${COMPARISON_BENCHMARK}) +target_link_libraries(benchmark_comparison PUBLIC xtensor ${GBENCHMARK_LIBRARIES}) +target_include_directories(benchmark_comparison PRIVATE ${XTENSOR_INCLUDE_DIR} ${GBENCHMARK_INCLUDE_DIRS}) + +add_custom_target(xcomparison + COMMAND benchmark_comparison + DEPENDS benchmark_comparison) diff --git a/benchmark/comparison/blas1_comparison.cpp b/benchmark/comparison/blas1_comparison.cpp new file mode 100644 index 000000000..4dab037dc --- /dev/null +++ b/benchmark/comparison/blas1_comparison.cpp @@ -0,0 +1,211 @@ +/*************************************************************************** + * Comparison benchmarks: BLAS1 operations + * Comparing raw C++ vs xtensor performance + ****************************************************************************/ + +#include +#include +#include + +#include "xtensor/containers/xarray.hpp" +#include "xtensor/containers/xtensor.hpp" +#include "xtensor/core/xnoalias.hpp" + +namespace xt::comparison +{ + + //======================================================================== + // Vector Addition: z = x + y + //======================================================================== + + // Raw C++ implementation with std::vector + static void add_vector_raw_cpp(benchmark::State& state) + { + using value_type = double; + using size_type = std::size_t; + + const size_type size = state.range(0); + std::vector x(size, 1.0); + std::vector y(size, 2.0); + std::vector z(size); + + for (auto _ : state) + { + for (size_type i = 0; i < size; ++i) + { + z[i] = x[i] + y[i]; + } + benchmark::DoNotOptimize(z.data()); + } + } + + // xtensor implementation with xarray + static void add_vector_xtensor_xarray(benchmark::State& state) + { + using size_type = std::size_t; + + const size_type size = state.range(0); + xarray x = xt::ones({size}); + xarray y = 2.0 * xt::ones({size}); + xarray z; + + for (auto _ : state) + { + z = x + y; + benchmark::DoNotOptimize(z.data()); + } + } + + // xtensor implementation with xtensor (fixed size) + static void add_vector_xtensor_xtensor(benchmark::State& state) + { + using size_type = std::size_t; + + const size_type size = state.range(0); + xtensor x = xt::ones({size}); + xtensor y = 2.0 * xt::ones({size}); + xtensor z; + + for (auto _ : state) + { + z = x + y; + benchmark::DoNotOptimize(z.data()); + } + } + + // xtensor with noalias (avoids temporary allocation) + static void add_vector_xtensor_noalias(benchmark::State& state) + { + using size_type = std::size_t; + + const size_type size = state.range(0); + xtensor x = xt::ones({size}); + xtensor y = 2.0 * xt::ones({size}); + xtensor z = xt::zeros({size}); + + for (auto _ : state) + { + xt::noalias(z) = x + y; + benchmark::DoNotOptimize(z.data()); + } + } + + //======================================================================== + // Scalar Addition: z = x + a (add_scalar) + //======================================================================== + + // Raw C++ + static void add_scalar_raw_cpp(benchmark::State& state) + { + using value_type = double; + using size_type = std::size_t; + + const size_type size = state.range(0); + const value_type a = 5.0; + std::vector x(size, 1.0); + std::vector z(size); + + for (auto _ : state) + { + for (size_type i = 0; i < size; ++i) + { + z[i] = x[i] + a; + } + benchmark::DoNotOptimize(z.data()); + } + } + + // xtensor + static void add_scalar_xtensor(benchmark::State& state) + { + using size_type = std::size_t; + + const size_type size = state.range(0); + const double a = 5.0; + xtensor x = xt::ones({size}); + xtensor z; + + for (auto _ : state) + { + z = x + a; + benchmark::DoNotOptimize(z.data()); + } + } + + // xtensor with noalias + static void add_scalar_xtensor_noalias(benchmark::State& state) + { + using size_type = std::size_t; + + const size_type size = state.range(0); + const double a = 5.0; + xtensor x = xt::ones({size}); + xtensor z = xt::zeros({size}); + + for (auto _ : state) + { + xt::noalias(z) = x + a; + benchmark::DoNotOptimize(z.data()); + } + } + + //======================================================================== + // Scalar Multiplication: y = a * x + //======================================================================== + + // Raw C++ + static void mul_scalar_raw_cpp(benchmark::State& state) + { + using value_type = double; + using size_type = std::size_t; + + const size_type size = state.range(0); + const value_type a = 2.5; + std::vector x(size, 1.0); + std::vector y(size); + + for (auto _ : state) + { + for (size_type i = 0; i < size; ++i) + { + y[i] = a * x[i]; + } + benchmark::DoNotOptimize(y.data()); + } + } + + // xtensor + static void mul_scalar_xtensor(benchmark::State& state) + { + using size_type = std::size_t; + + const size_type size = state.range(0); + const double a = 2.5; + xtensor x = xt::ones({size}); + xtensor y; + + for (auto _ : state) + { + y = a * x; + benchmark::DoNotOptimize(y.data()); + } + } + + //======================================================================== + // Register benchmarks with different sizes + //======================================================================== + + // Vector sizes to test: 64, 256, 1024, 4096, 16384 + BENCHMARK(add_vector_raw_cpp)->Range(64, 16384)->RangeMultiplier(4); + BENCHMARK(add_vector_xtensor_xarray)->Range(64, 16384)->RangeMultiplier(4); + BENCHMARK(add_vector_xtensor_xtensor)->Range(64, 16384)->RangeMultiplier(4); + BENCHMARK(add_vector_xtensor_noalias)->Range(64, 16384)->RangeMultiplier(4); + + BENCHMARK(add_scalar_raw_cpp)->Range(64, 16384)->RangeMultiplier(4); + BENCHMARK(add_scalar_xtensor)->Range(64, 16384)->RangeMultiplier(4); + BENCHMARK(add_scalar_xtensor_noalias)->Range(64, 16384)->RangeMultiplier(4); + + BENCHMARK(mul_scalar_raw_cpp)->Range(64, 16384)->RangeMultiplier(4); + BENCHMARK(mul_scalar_xtensor)->Range(64, 16384)->RangeMultiplier(4); + +} diff --git a/benchmark/comparison/comparison_main.cpp b/benchmark/comparison/comparison_main.cpp new file mode 100644 index 000000000..984e4e622 --- /dev/null +++ b/benchmark/comparison/comparison_main.cpp @@ -0,0 +1,20 @@ +/*************************************************************************** + * Comparison benchmarks: xtensor vs raw C++ + ****************************************************************************/ + +#include +#include + +// Custom main for comparison benchmarks +int main(int argc, char** argv) +{ + std::cout << "=== COMPARISON BENCHMARKS: xtensor vs raw C++ ===" << std::endl; + std::cout << "Each benchmark runs multiple implementations for direct comparison\n" << std::endl; + + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + { + return 1; + } + benchmark::RunSpecifiedBenchmarks(); +} From 6fe2522c4e9aafe778718f5bd179fa86d6ae05c9 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Thu, 8 Jan 2026 00:05:33 +0100 Subject: [PATCH 2/6] Simplify comparison benchmarks code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce code duplication and improve readability: - Add helper functions for xtensor/xarray creation - Add BENCHMARK_LOOP macro to reduce boilerplate - Add REGISTER_BENCHMARK macro for standard sizes - Rename: raw_cpp → std, shorten xtensor variants - Add size 8 to benchmark ranges - Use constexpr for scalar values Changes: - blas1_comparison.cpp: 211 → 197 lines (-14 lines) - Add min_size=8, max_size=16384, multiplier=4 constants - Simpler, more maintainable code 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- benchmark/comparison/blas1_comparison.cpp | 252 ++++++++++------------ 1 file changed, 119 insertions(+), 133 deletions(-) diff --git a/benchmark/comparison/blas1_comparison.cpp b/benchmark/comparison/blas1_comparison.cpp index 4dab037dc..0a3c8611c 100644 --- a/benchmark/comparison/blas1_comparison.cpp +++ b/benchmark/comparison/blas1_comparison.cpp @@ -15,197 +15,183 @@ namespace xt::comparison { //======================================================================== - // Vector Addition: z = x + y + // Helpers //======================================================================== - // Raw C++ implementation with std::vector - static void add_vector_raw_cpp(benchmark::State& state) + // Benchmark range configuration + constexpr std::size_t min_size = 8; + constexpr std::size_t max_size = 16384; + constexpr std::size_t multiplier = 4; + + // Helper to create xtensor vectors + inline auto make_xtensor(std::size_t size, double val) { - using value_type = double; - using size_type = std::size_t; - - const size_type size = state.range(0); - std::vector x(size, 1.0); - std::vector y(size, 2.0); - std::vector z(size); - - for (auto _ : state) - { - for (size_type i = 0; i < size; ++i) - { - z[i] = x[i] + y[i]; - } - benchmark::DoNotOptimize(z.data()); - } + return xt::xtensor::from_shape({size}) * val; } - // xtensor implementation with xarray - static void add_vector_xtensor_xarray(benchmark::State& state) + inline auto make_xtensor_zeros(std::size_t size) { - using size_type = std::size_t; + auto c = xt::xtensor::from_shape({size}); + c.fill(0); + return c; + } - const size_type size = state.range(0); - xarray x = xt::ones({size}); - xarray y = 2.0 * xt::ones({size}); - xarray z; + // Helper to create xarray + inline auto make_xarray(std::size_t size, double val) + { + return xt::xarray::from_shape({size}) * val; + } - for (auto _ : state) - { - z = x + y; - benchmark::DoNotOptimize(z.data()); + // Macro for benchmark loop (reduces boilerplate) + #define BENCHMARK_LOOP(state, container, ...) \ + for (auto _ : state) { \ + __VA_ARGS__; \ + benchmark::DoNotOptimize(container.data()); \ } - } - // xtensor implementation with xtensor (fixed size) - static void add_vector_xtensor_xtensor(benchmark::State& state) + // Macro for registering benchmarks with standard sizes + #define REGISTER_BENCHMARK(func) \ + BENCHMARK(func)->Range(min_size, max_size)->RangeMultiplier(multiplier) + + //======================================================================== + // Vector Addition: z = x + y + //======================================================================== + + static void add_vector_std(benchmark::State& state) { - using size_type = std::size_t; + const std::size_t size = state.range(0); + std::vector x(size, 1.0); + std::vector y(size, 2.0); + std::vector z(size); + + BENCHMARK_LOOP(state, z, + for (std::size_t i = 0; i < size; ++i) + z[i] = x[i] + y[i]; + ); + } - const size_type size = state.range(0); - xtensor x = xt::ones({size}); - xtensor y = 2.0 * xt::ones({size}); - xtensor z; + static void add_vector_xarray(benchmark::State& state) + { + const std::size_t size = state.range(0); + auto x = make_xarray(size, 1.0); + auto y = make_xarray(size, 2.0); + xt::xarray z; - for (auto _ : state) - { + BENCHMARK_LOOP(state, z, z = x + y; - benchmark::DoNotOptimize(z.data()); - } + ); } - // xtensor with noalias (avoids temporary allocation) - static void add_vector_xtensor_noalias(benchmark::State& state) + static void add_vector_xtensor(benchmark::State& state) { - using size_type = std::size_t; + const std::size_t size = state.range(0); + auto x = make_xtensor(size, 1.0); + auto y = make_xtensor(size, 2.0); + xt::xtensor z; - const size_type size = state.range(0); - xtensor x = xt::ones({size}); - xtensor y = 2.0 * xt::ones({size}); - xtensor z = xt::zeros({size}); + BENCHMARK_LOOP(state, z, + z = x + y; + ); + } - for (auto _ : state) - { + static void add_vector_noalias(benchmark::State& state) + { + const std::size_t size = state.range(0); + auto x = make_xtensor(size, 1.0); + auto y = make_xtensor(size, 2.0); + auto z = make_xtensor_zeros(size); + + BENCHMARK_LOOP(state, z, xt::noalias(z) = x + y; - benchmark::DoNotOptimize(z.data()); - } + ); } //======================================================================== - // Scalar Addition: z = x + a (add_scalar) + // Scalar Addition: z = x + a //======================================================================== - // Raw C++ - static void add_scalar_raw_cpp(benchmark::State& state) + static void add_scalar_std(benchmark::State& state) { - using value_type = double; - using size_type = std::size_t; - - const size_type size = state.range(0); - const value_type a = 5.0; - std::vector x(size, 1.0); - std::vector z(size); - - for (auto _ : state) - { - for (size_type i = 0; i < size; ++i) - { + const std::size_t size = state.range(0); + constexpr double a = 5.0; + std::vector x(size, 1.0); + std::vector z(size); + + BENCHMARK_LOOP(state, z, + for (std::size_t i = 0; i < size; ++i) z[i] = x[i] + a; - } - benchmark::DoNotOptimize(z.data()); - } + ); } - // xtensor static void add_scalar_xtensor(benchmark::State& state) { - using size_type = std::size_t; + const std::size_t size = state.range(0); + constexpr double a = 5.0; + auto x = make_xtensor(size, 1.0); + xt::xtensor z; - const size_type size = state.range(0); - const double a = 5.0; - xtensor x = xt::ones({size}); - xtensor z; - - for (auto _ : state) - { + BENCHMARK_LOOP(state, z, z = x + a; - benchmark::DoNotOptimize(z.data()); - } + ); } - // xtensor with noalias - static void add_scalar_xtensor_noalias(benchmark::State& state) + static void add_scalar_noalias(benchmark::State& state) { - using size_type = std::size_t; + const std::size_t size = state.range(0); + constexpr double a = 5.0; + auto x = make_xtensor(size, 1.0); + auto z = make_xtensor_zeros(size); - const size_type size = state.range(0); - const double a = 5.0; - xtensor x = xt::ones({size}); - xtensor z = xt::zeros({size}); - - for (auto _ : state) - { + BENCHMARK_LOOP(state, z, xt::noalias(z) = x + a; - benchmark::DoNotOptimize(z.data()); - } + ); } //======================================================================== // Scalar Multiplication: y = a * x //======================================================================== - // Raw C++ - static void mul_scalar_raw_cpp(benchmark::State& state) + static void mul_scalar_std(benchmark::State& state) { - using value_type = double; - using size_type = std::size_t; - - const size_type size = state.range(0); - const value_type a = 2.5; - std::vector x(size, 1.0); - std::vector y(size); - - for (auto _ : state) - { - for (size_type i = 0; i < size; ++i) - { + const std::size_t size = state.range(0); + constexpr double a = 2.5; + std::vector x(size, 1.0); + std::vector y(size); + + BENCHMARK_LOOP(state, y, + for (std::size_t i = 0; i < size; ++i) y[i] = a * x[i]; - } - benchmark::DoNotOptimize(y.data()); - } + ); } - // xtensor static void mul_scalar_xtensor(benchmark::State& state) { - using size_type = std::size_t; + const std::size_t size = state.range(0); + constexpr double a = 2.5; + auto x = make_xtensor(size, 1.0); + xt::xtensor y; - const size_type size = state.range(0); - const double a = 2.5; - xtensor x = xt::ones({size}); - xtensor y; - - for (auto _ : state) - { + BENCHMARK_LOOP(state, y, y = a * x; - benchmark::DoNotOptimize(y.data()); - } + ); } //======================================================================== - // Register benchmarks with different sizes + // Register benchmarks //======================================================================== - // Vector sizes to test: 64, 256, 1024, 4096, 16384 - BENCHMARK(add_vector_raw_cpp)->Range(64, 16384)->RangeMultiplier(4); - BENCHMARK(add_vector_xtensor_xarray)->Range(64, 16384)->RangeMultiplier(4); - BENCHMARK(add_vector_xtensor_xtensor)->Range(64, 16384)->RangeMultiplier(4); - BENCHMARK(add_vector_xtensor_noalias)->Range(64, 16384)->RangeMultiplier(4); + // Vector + Vector + REGISTER_BENCHMARK(add_vector_std); + REGISTER_BENCHMARK(add_vector_xarray); + REGISTER_BENCHMARK(add_vector_xtensor); + REGISTER_BENCHMARK(add_vector_noalias); - BENCHMARK(add_scalar_raw_cpp)->Range(64, 16384)->RangeMultiplier(4); - BENCHMARK(add_scalar_xtensor)->Range(64, 16384)->RangeMultiplier(4); - BENCHMARK(add_scalar_xtensor_noalias)->Range(64, 16384)->RangeMultiplier(4); + // Scalar operations + REGISTER_BENCHMARK(add_scalar_std); + REGISTER_BENCHMARK(add_scalar_xtensor); + REGISTER_BENCHMARK(add_scalar_noalias); - BENCHMARK(mul_scalar_raw_cpp)->Range(64, 16384)->RangeMultiplier(4); - BENCHMARK(mul_scalar_xtensor)->Range(64, 16384)->RangeMultiplier(4); + REGISTER_BENCHMARK(mul_scalar_std); + REGISTER_BENCHMARK(mul_scalar_xtensor); } From 911413ac806bfa135a71b234de52de5d9075b5a7 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Thu, 8 Jan 2026 11:18:51 +0100 Subject: [PATCH 3/6] Add xbenchmark/ to gitignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4a5bcec30..d1e77f247 100644 --- a/.gitignore +++ b/.gitignore @@ -66,3 +66,4 @@ __pycache__ # Allow tag JSONs under etc/xeus-cpp !etc/xeus-cpp/tags.d/ +xbenchmark/ From cff0a3cd8c5f1a07b1faf55d7d90628fbafc6ee2 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Thu, 8 Jan 2026 11:25:20 +0100 Subject: [PATCH 4/6] Fix formatting in comparison benchmarks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- benchmark/comparison/blas1_comparison.cpp | 58 ++++++++--------------- benchmark/comparison/comparison_main.cpp | 1 + 2 files changed, 20 insertions(+), 39 deletions(-) diff --git a/benchmark/comparison/blas1_comparison.cpp b/benchmark/comparison/blas1_comparison.cpp index 0a3c8611c..7b7dfc79f 100644 --- a/benchmark/comparison/blas1_comparison.cpp +++ b/benchmark/comparison/blas1_comparison.cpp @@ -5,6 +5,7 @@ #include #include + #include #include "xtensor/containers/xarray.hpp" @@ -42,16 +43,16 @@ namespace xt::comparison return xt::xarray::from_shape({size}) * val; } - // Macro for benchmark loop (reduces boilerplate) - #define BENCHMARK_LOOP(state, container, ...) \ - for (auto _ : state) { \ - __VA_ARGS__; \ - benchmark::DoNotOptimize(container.data()); \ - } +// Macro for benchmark loop (reduces boilerplate) +#define BENCHMARK_LOOP(state, container, ...) \ + for (auto _ : state) \ + { \ + __VA_ARGS__; \ + benchmark::DoNotOptimize(container.data()); \ + } - // Macro for registering benchmarks with standard sizes - #define REGISTER_BENCHMARK(func) \ - BENCHMARK(func)->Range(min_size, max_size)->RangeMultiplier(multiplier) +// Macro for registering benchmarks with standard sizes +#define REGISTER_BENCHMARK(func) BENCHMARK(func)->Range(min_size, max_size)->RangeMultiplier(multiplier) //======================================================================== // Vector Addition: z = x + y @@ -64,10 +65,7 @@ namespace xt::comparison std::vector y(size, 2.0); std::vector z(size); - BENCHMARK_LOOP(state, z, - for (std::size_t i = 0; i < size; ++i) - z[i] = x[i] + y[i]; - ); + BENCHMARK_LOOP(state, z, for (std::size_t i = 0; i < size; ++i) z[i] = x[i] + y[i];); } static void add_vector_xarray(benchmark::State& state) @@ -77,9 +75,7 @@ namespace xt::comparison auto y = make_xarray(size, 2.0); xt::xarray z; - BENCHMARK_LOOP(state, z, - z = x + y; - ); + BENCHMARK_LOOP(state, z, z = x + y;); } static void add_vector_xtensor(benchmark::State& state) @@ -89,9 +85,7 @@ namespace xt::comparison auto y = make_xtensor(size, 2.0); xt::xtensor z; - BENCHMARK_LOOP(state, z, - z = x + y; - ); + BENCHMARK_LOOP(state, z, z = x + y;); } static void add_vector_noalias(benchmark::State& state) @@ -101,9 +95,7 @@ namespace xt::comparison auto y = make_xtensor(size, 2.0); auto z = make_xtensor_zeros(size); - BENCHMARK_LOOP(state, z, - xt::noalias(z) = x + y; - ); + BENCHMARK_LOOP(state, z, xt::noalias(z) = x + y;); } //======================================================================== @@ -117,10 +109,7 @@ namespace xt::comparison std::vector x(size, 1.0); std::vector z(size); - BENCHMARK_LOOP(state, z, - for (std::size_t i = 0; i < size; ++i) - z[i] = x[i] + a; - ); + BENCHMARK_LOOP(state, z, for (std::size_t i = 0; i < size; ++i) z[i] = x[i] + a;); } static void add_scalar_xtensor(benchmark::State& state) @@ -130,9 +119,7 @@ namespace xt::comparison auto x = make_xtensor(size, 1.0); xt::xtensor z; - BENCHMARK_LOOP(state, z, - z = x + a; - ); + BENCHMARK_LOOP(state, z, z = x + a;); } static void add_scalar_noalias(benchmark::State& state) @@ -142,9 +129,7 @@ namespace xt::comparison auto x = make_xtensor(size, 1.0); auto z = make_xtensor_zeros(size); - BENCHMARK_LOOP(state, z, - xt::noalias(z) = x + a; - ); + BENCHMARK_LOOP(state, z, xt::noalias(z) = x + a;); } //======================================================================== @@ -158,10 +143,7 @@ namespace xt::comparison std::vector x(size, 1.0); std::vector y(size); - BENCHMARK_LOOP(state, y, - for (std::size_t i = 0; i < size; ++i) - y[i] = a * x[i]; - ); + BENCHMARK_LOOP(state, y, for (std::size_t i = 0; i < size; ++i) y[i] = a * x[i];); } static void mul_scalar_xtensor(benchmark::State& state) @@ -171,9 +153,7 @@ namespace xt::comparison auto x = make_xtensor(size, 1.0); xt::xtensor y; - BENCHMARK_LOOP(state, y, - y = a * x; - ); + BENCHMARK_LOOP(state, y, y = a * x;); } //======================================================================== diff --git a/benchmark/comparison/comparison_main.cpp b/benchmark/comparison/comparison_main.cpp index 984e4e622..44eee867f 100644 --- a/benchmark/comparison/comparison_main.cpp +++ b/benchmark/comparison/comparison_main.cpp @@ -3,6 +3,7 @@ ****************************************************************************/ #include + #include // Custom main for comparison benchmarks From a2abe8634f5f630437d292c1b961527b7fcb4909 Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Thu, 8 Jan 2026 13:07:51 +0100 Subject: [PATCH 5/6] Remove debug output from comparison benchmark main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- benchmark/comparison/comparison_main.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/benchmark/comparison/comparison_main.cpp b/benchmark/comparison/comparison_main.cpp index 44eee867f..c71246d6c 100644 --- a/benchmark/comparison/comparison_main.cpp +++ b/benchmark/comparison/comparison_main.cpp @@ -2,16 +2,11 @@ * Comparison benchmarks: xtensor vs raw C++ ****************************************************************************/ -#include - #include // Custom main for comparison benchmarks int main(int argc, char** argv) { - std::cout << "=== COMPARISON BENCHMARKS: xtensor vs raw C++ ===" << std::endl; - std::cout << "Each benchmark runs multiple implementations for direct comparison\n" << std::endl; - benchmark::Initialize(&argc, argv); if (benchmark::ReportUnrecognizedArguments(argc, argv)) { From 8647ff7c4ad93393f7296eaa392032480e74e0ff Mon Sep 17 00:00:00 2001 From: sbstndb/sbstndbs Date: Thu, 8 Jan 2026 13:09:14 +0100 Subject: [PATCH 6/6] Remove xbenchmark/ from gitignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .gitignore | 1 - xbenchmark | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) create mode 160000 xbenchmark diff --git a/.gitignore b/.gitignore index d1e77f247..4a5bcec30 100644 --- a/.gitignore +++ b/.gitignore @@ -66,4 +66,3 @@ __pycache__ # Allow tag JSONs under etc/xeus-cpp !etc/xeus-cpp/tags.d/ -xbenchmark/ diff --git a/xbenchmark b/xbenchmark new file mode 160000 index 000000000..4d6334a10 --- /dev/null +++ b/xbenchmark @@ -0,0 +1 @@ +Subproject commit 4d6334a1024fa8f00e9dfd5368c7936992c4748d