diff --git a/root/hist/hist/CMakeLists.txt b/root/hist/hist/CMakeLists.txt index 0154acde..4bff354a 100644 --- a/root/hist/hist/CMakeLists.txt +++ b/root/hist/hist/CMakeLists.txt @@ -5,13 +5,18 @@ RB_ADD_GBENCHMARK(HistBenchmarks LIBRARIES Core Hist MathCore) RB_ADD_GBENCHMARK(THistBenchmarks - THistFillBenchmarks.cxx - LABEL short - LIBRARIES Hist Core) + THistFillDoubleBenchmarks.cxx + THistFillFloatBenchmarks.cxx + THistFillIntBenchmarks.cxx + LABEL short + LIBRARIES Hist Core) if(ROOT_root7_FOUND) RB_ADD_GBENCHMARK(RHistBenchmarks - RHistFillBenchmarks.cxx + RHistFillDoubleBenchmarks.cxx + RHistFillFloatBenchmarks.cxx + RHistFillIntBenchmarks.cxx + RHistFillLongLongBenchmarks.cxx LABEL short LIBRARIES ROOTHist Core) endif() diff --git a/root/hist/hist/RHistFillBenchmarks.cxx b/root/hist/hist/RHistFillDoubleBenchmarks.cxx similarity index 61% rename from root/hist/hist/RHistFillBenchmarks.cxx rename to root/hist/hist/RHistFillDoubleBenchmarks.cxx index f9c193f7..c656d5db 100644 --- a/root/hist/hist/RHistFillBenchmarks.cxx +++ b/root/hist/hist/RHistFillDoubleBenchmarks.cxx @@ -34,7 +34,7 @@ static void ConcurrentFillArguments(benchmark::internal::Benchmark *b) using CoordArray_t = ROOT::Experimental::Hist::RCoordArray<2>; // Create array for x coordinates -std::vector MakeCoorVec(int nbOfDataPoints) +static std::vector MakeCoorVec(int nbOfDataPoints) { std::vector vec; for (int j = 0; j < nbOfDataPoints; ++j) { @@ -45,7 +45,7 @@ std::vector MakeCoorVec(int nbOfDataPoints) } // Create array for weights -std::vector MakeWeightVec(int nbOfDataPoints) +std::vector MakeDoubleWeightVec(int nbOfDataPoints) { std::vector vec; for (int j = 0; j < nbOfDataPoints; ++j) { @@ -56,23 +56,23 @@ std::vector MakeWeightVec(int nbOfDataPoints) } // Arrays of coordinates and weights -std::vector coords = MakeCoorVec(3000000); -std::vector weights = MakeWeightVec(3000000); +static std::vector coords = MakeCoorVec(3000000); +std::vector weightsDouble = MakeDoubleWeightVec(3000000); // Histograms with different bin configurations for Fill -ROOT::Experimental::RH2D hist1{{10, 0.1, 1.}, {10 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist2{{10, 0.1, 1.}, {100 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist3{{10, 0.1, 1.}, {1000 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist4{{100, 0.1, 1.}, {10 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist5{{100, 0.1, 1.}, {100 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist6{{100, 0.1, 1.}, {1000 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist7{{1000, 0.1, 1.}, {10 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist8{{1000, 0.1, 1.}, {100 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist9{{1000, 0.1, 1.}, {1000 / 2, 0., 10.}}; - -std::map> histFill = { { 10, { { 5, &hist1 }, { 50, &hist2 }, { 500, &hist3} } }, - { 100, { { 5, &hist4 }, { 50, &hist5 }, { 500, &hist6 } } }, - { 1000, { { 5, &hist7 }, { 50, &hist8 }, { 500, &hist9 } } } }; +ROOT::Experimental::RH2D hist1Double{{10, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist2Double{{10, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist3Double{{10, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist4Double{{100, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist5Double{{100, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist6Double{{100, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist7Double{{1000, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist8Double{{1000, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist9Double{{1000, 0.1, 1.}, {1000 / 2, 0., 10.}}; + +std::map> histFillDouble = { { 10, { { 5, &hist1Double }, { 50, &hist2Double }, { 500, &hist3Double} } }, + { 100, { { 5, &hist4Double }, { 50, &hist5Double }, { 500, &hist6Double } } }, + { 1000, { { 5, &hist7Double }, { 50, &hist8Double }, { 500, &hist9Double } } } }; static void FillHist(int nbOfDataPoints, ROOT::Experimental::RH2D * hist) { @@ -89,51 +89,51 @@ static void FillHist(int nbOfDataPoints, ROOT::Experimental::RH2D * hist) } // Benchmark for simple Fill on 2D hist -static void BM_RHist_Fill(benchmark::State &state) +static void BM_RHist_Fill_Double(benchmark::State &state) { int nbOfDataPoints = state.range(0); int nbOfBinsForFirstAxis = state.range(1); int nbOfBinsForSecondAxis = state.range(2); - auto hist = histFill[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; + auto hist = histFillDouble[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; for (auto _ : state) FillHist(nbOfDataPoints, hist); } -BENCHMARK(BM_RHist_Fill) -> Apply(FillArguments); +BENCHMARK(BM_RHist_Fill_Double) -> Apply(FillArguments); // Histograms with different bin configurations for FillN -ROOT::Experimental::RH2D hist11{{10, 0.1, 1.}, {10 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist12{{10, 0.1, 1.}, {100 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist13{{10, 0.1, 1.}, {1000 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist14{{100, 0.1, 1.}, {10 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist15{{100, 0.1, 1.}, {100 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist16{{100, 0.1, 1.}, {1000 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist17{{1000, 0.1, 1.}, {10 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist18{{1000, 0.1, 1.}, {100 / 2, 0., 10.}}; -ROOT::Experimental::RH2D hist19{{1000, 0.1, 1.}, {1000 / 2, 0., 10.}}; - -std::map> histFillN = { { 10, { { 5, &hist11 }, { 50, &hist12 }, { 500, &hist13} } }, - { 100, { { 5, &hist14 }, { 50, &hist15 }, { 500, &hist16 } } }, - { 1000, { { 5, &hist17 }, { 50, &hist18 }, { 500, &hist19 } } } }; +ROOT::Experimental::RH2D hist11Double{{10, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist12Double{{10, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist13Double{{10, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist14Double{{100, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist15Double{{100, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist16Double{{100, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist17Double{{1000, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist18Double{{1000, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2D hist19Double{{1000, 0.1, 1.}, {1000 / 2, 0., 10.}}; + +std::map> histFillNDouble = { { 10, { { 5, &hist11Double }, { 50, &hist12Double }, { 500, &hist13Double} } }, + { 100, { { 5, &hist14Double }, { 50, &hist15Double }, { 500, &hist16Double } } }, + { 1000, { { 5, &hist17Double }, { 50, &hist18Double }, { 500, &hist19Double } } } }; // Benchmark for simple FillN on 2D hist -static void BM_RHist_FillN(benchmark::State &state) +static void BM_RHist_FillN_Double(benchmark::State &state) { int nbOfDataPoints = state.range(0); int nbOfBinsForFirstAxis = state.range(1); int nbOfBinsForSecondAxis = state.range(2); - auto hist = histFillN[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; + auto hist = histFillNDouble[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; for (auto _ : state) { - // FillN without weight - hist->FillN(std::span(&coords[0], nbOfDataPoints), std::span(&weights[0], nbOfDataPoints)); // FillN with weights + hist->FillN(std::span(&coords[0], nbOfDataPoints), std::span(&weightsDouble[0], nbOfDataPoints)); + // FillN without weight hist->FillN(std::span(&coords[0], nbOfDataPoints)); } } -BENCHMARK(BM_RHist_FillN) -> Apply(FillArguments); +BENCHMARK(BM_RHist_FillN_Double) -> Apply(FillArguments); using Filler_t = ROOT::Experimental::RHistConcurrentFiller; @@ -141,7 +141,7 @@ using Filler_t = ROOT::Experimental::RHistConcurrentFiller(i); + double d = static_cast< double >(i); filler.Fill({d / nbOfDataPoints, d / (nbOfDataPoints / 10)}); } } @@ -149,7 +149,7 @@ void fillWithoutWeight(Filler_t filler, int nbOfDataPoints) void fillWithWeights(Filler_t filler, int nbOfDataPoints) { for (int i = 0; i < nbOfDataPoints; ++i) { - float d = static_cast< float >(i); + double d = static_cast< double >(i); filler.Fill({d / nbOfDataPoints, d / (nbOfDataPoints / 10)}, d); } } diff --git a/root/hist/hist/RHistFillFloatBenchmarks.cxx b/root/hist/hist/RHistFillFloatBenchmarks.cxx new file mode 100644 index 00000000..8c7dfc02 --- /dev/null +++ b/root/hist/hist/RHistFillFloatBenchmarks.cxx @@ -0,0 +1,128 @@ +#include "ROOT/RHist.hxx" +#include "ROOT/span.hxx" + +#include "benchmark/benchmark.h" + +#include +#include +#include +#include +#include + +// Define benchmark arguments +static void FillArguments(benchmark::internal::Benchmark *b) +{ + // Number of data points + for(int i = 3; i <= 3000000; i *= 100) + // Number of bins + for(int k = 10; k <= 1000; k *= 10) + b->Args({i, k, k / 2}); +} + +using CoordArray_t = ROOT::Experimental::Hist::RCoordArray<2>; + +// Create array for x coordinates +static std::vector MakeCoorVec(int nbOfDataPoints) +{ + std::vector vec; + for (int j = 0; j < nbOfDataPoints; ++j) { + double d = static_cast< double >(j); + vec.push_back({ d / nbOfDataPoints, d / (nbOfDataPoints / 10) }); + } + return vec; +} + +// Create array for weights +std::vector MakeFloatWeightVec(int nbOfDataPoints) +{ + std::vector vec; + for (int j = 0; j < nbOfDataPoints; ++j) { + float d = static_cast< float >(j); + vec.push_back(d); + } + return vec; +} + +// Arrays of coordinates and weights +static std::vector coords = MakeCoorVec(3000000); +std::vector weightsFloat = MakeFloatWeightVec(3000000); + +// Histograms with different bin configurations for Fill +ROOT::Experimental::RH2F hist1Float{{10, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist2Float{{10, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist3Float{{10, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist4Float{{100, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist5Float{{100, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist6Float{{100, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist7Float{{1000, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist8Float{{1000, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist9Float{{1000, 0.1, 1.}, {1000 / 2, 0., 10.}}; + +std::map> histFillFloat = { { 10, { { 5, &hist1Float }, { 50, &hist2Float }, { 500, &hist3Float} } }, + { 100, { { 5, &hist4Float }, { 50, &hist5Float }, { 500, &hist6Float } } }, + { 1000, { { 5, &hist7Float }, { 50, &hist8Float }, { 500, &hist9Float } } } }; + +static void FillHist(int nbOfDataPoints, ROOT::Experimental::RH2F * hist) +{ + // Fill without weight + for (int i = 0; i < nbOfDataPoints; ++i) { + double d = static_cast< double >(i); + hist->Fill({d / nbOfDataPoints, d / (nbOfDataPoints / 10)}); + } + // Fill with weights + for (int i = 0; i < nbOfDataPoints; ++i) { + double d = static_cast< double >(i); + float w = static_cast< float >(i); + hist->Fill({d / nbOfDataPoints, d / (nbOfDataPoints / 10)}, w); + } +} + +// Benchmark for simple Fill on 2D hist +static void BM_RHist_Fill_Float(benchmark::State &state) +{ + int nbOfDataPoints = state.range(0); + int nbOfBinsForFirstAxis = state.range(1); + int nbOfBinsForSecondAxis = state.range(2); + + auto hist = histFillFloat[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; + + for (auto _ : state) + FillHist(nbOfDataPoints, hist); +} +BENCHMARK(BM_RHist_Fill_Float) -> Apply(FillArguments); + +// Histograms with different bin configurations for FillN +ROOT::Experimental::RH2F hist11Float{{10, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist12Float{{10, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist13Float{{10, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist14Float{{100, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist15Float{{100, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist16Float{{100, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist17Float{{1000, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist18Float{{1000, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2F hist19Float{{1000, 0.1, 1.}, {1000 / 2, 0., 10.}}; + +std::map> histFillNFloat = { { 10, { { 5, &hist11Float }, { 50, &hist12Float }, { 500, &hist13Float} } }, + { 100, { { 5, &hist14Float }, { 50, &hist15Float }, { 500, &hist16Float } } }, + { 1000, { { 5, &hist17Float }, { 50, &hist18Float }, { 500, &hist19Float } } } }; + +// Benchmark for simple FillN on 2D hist +static void BM_RHist_FillN_Float(benchmark::State &state) +{ + int nbOfDataPoints = state.range(0); + int nbOfBinsForFirstAxis = state.range(1); + int nbOfBinsForSecondAxis = state.range(2); + + auto hist = histFillNFloat[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; + + for (auto _ : state) { + // FillN with weights + hist->FillN(std::span(&coords[0], nbOfDataPoints), std::span(&weightsFloat[0], nbOfDataPoints)); + // FillN without weight + hist->FillN(std::span(&coords[0], nbOfDataPoints)); + } +} +BENCHMARK(BM_RHist_FillN_Float) -> Apply(FillArguments); + +// // Call main() +// BENCHMARK_MAIN(); diff --git a/root/hist/hist/RHistFillIntBenchmarks.cxx b/root/hist/hist/RHistFillIntBenchmarks.cxx new file mode 100644 index 00000000..b325976a --- /dev/null +++ b/root/hist/hist/RHistFillIntBenchmarks.cxx @@ -0,0 +1,128 @@ +#include "ROOT/RHist.hxx" +#include "ROOT/span.hxx" + +#include "benchmark/benchmark.h" + +#include +#include +#include +#include +#include + +// Define benchmark arguments +static void FillArguments(benchmark::internal::Benchmark *b) +{ + // Number of data points + for(int i = 3; i <= 3000000; i *= 100) + // Number of bins + for(int k = 10; k <= 1000; k *= 10) + b->Args({i, k, k / 2}); +} + +using CoordArray_t = ROOT::Experimental::Hist::RCoordArray<2>; + +// Create array for x coordinates +static std::vector MakeCoorVec(int nbOfDataPoints) +{ + std::vector vec; + for (int j = 0; j < nbOfDataPoints; ++j) { + double d = static_cast< double >(j); + vec.push_back({ d / nbOfDataPoints, d / (nbOfDataPoints / 10) }); + } + return vec; +} + +// Create array for weights +std::vector MakeIntWeightVec(int nbOfDataPoints) +{ + std::vector vec; + for (int j = 0; j < nbOfDataPoints; ++j) { + int d = static_cast< int >(j); + vec.push_back(d); + } + return vec; +} + +// Arrays of coordinates and weights +static std::vector coords = MakeCoorVec(3000000); +std::vector weightsInt = MakeIntWeightVec(3000000); + +// Histograms with different bin configurations for Fill +ROOT::Experimental::RH2I hist1Int{{10, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist2Int{{10, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist3Int{{10, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist4Int{{100, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist5Int{{100, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist6Int{{100, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist7Int{{1000, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist8Int{{1000, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist9Int{{1000, 0.1, 1.}, {1000 / 2, 0., 10.}}; + +std::map> histFillInt = { { 10, { { 5, &hist1Int }, { 50, &hist2Int }, { 500, &hist3Int} } }, + { 100, { { 5, &hist4Int }, { 50, &hist5Int }, { 500, &hist6Int } } }, + { 1000, { { 5, &hist7Int }, { 50, &hist8Int }, { 500, &hist9Int } } } }; + +static void FillHist(int nbOfDataPoints, ROOT::Experimental::RH2I * hist) +{ + // Fill without weight + for (int i = 0; i < nbOfDataPoints; ++i) { + double d = static_cast< double >(i); + hist->Fill({d / nbOfDataPoints, d / (nbOfDataPoints / 10)}); + } + // Fill with weights + for (int i = 0; i < nbOfDataPoints; ++i) { + double d = static_cast< double >(i); + int w = static_cast< int >(i); + hist->Fill({d / nbOfDataPoints, d / (nbOfDataPoints / 10)}, w); + } +} + +// Benchmark for simple Fill on 2D hist +static void BM_RHist_Fill_Int(benchmark::State &state) +{ + int nbOfDataPoints = state.range(0); + int nbOfBinsForFirstAxis = state.range(1); + int nbOfBinsForSecondAxis = state.range(2); + + auto hist = histFillInt[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; + + for (auto _ : state) + FillHist(nbOfDataPoints, hist); +} +BENCHMARK(BM_RHist_Fill_Int) -> Apply(FillArguments); + +// Histograms with different bin configurations for FillN +ROOT::Experimental::RH2I hist11Int{{10, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist12Int{{10, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist13Int{{10, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist14Int{{100, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist15Int{{100, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist16Int{{100, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist17Int{{1000, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist18Int{{1000, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2I hist19Int{{1000, 0.1, 1.}, {1000 / 2, 0., 10.}}; + +std::map> histFillNInt = { { 10, { { 5, &hist11Int }, { 50, &hist12Int }, { 500, &hist13Int} } }, + { 100, { { 5, &hist14Int }, { 50, &hist15Int }, { 500, &hist16Int } } }, + { 1000, { { 5, &hist17Int }, { 50, &hist18Int }, { 500, &hist19Int } } } }; + +// Benchmark for simple FillN on 2D hist +static void BM_RHist_FillN_Int(benchmark::State &state) +{ + int nbOfDataPoints = state.range(0); + int nbOfBinsForFirstAxis = state.range(1); + int nbOfBinsForSecondAxis = state.range(2); + + auto hist = histFillNInt[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; + + for (auto _ : state) { + // FillN with weights + hist->FillN(std::span(&coords[0], nbOfDataPoints), std::span(&weightsInt[0], nbOfDataPoints)); + // FillN without weight + hist->FillN(std::span(&coords[0], nbOfDataPoints)); + } +} +BENCHMARK(BM_RHist_FillN_Int) -> Apply(FillArguments); + +// // Call main() +// BENCHMARK_MAIN(); diff --git a/root/hist/hist/RHistFillLongLongBenchmarks.cxx b/root/hist/hist/RHistFillLongLongBenchmarks.cxx new file mode 100644 index 00000000..af26507d --- /dev/null +++ b/root/hist/hist/RHistFillLongLongBenchmarks.cxx @@ -0,0 +1,125 @@ +#include "ROOT/RHist.hxx" +#include "ROOT/span.hxx" + +#include "benchmark/benchmark.h" + +#include +#include + +// Define benchmark arguments +static void FillArguments(benchmark::internal::Benchmark *b) +{ + // Number of data points + for(int i = 3; i <= 3000000; i *= 100) + // Number of bins + for(int k = 10; k <= 1000; k *= 10) + b->Args({i, k, k / 2}); +} + +using CoordArray_t = ROOT::Experimental::Hist::RCoordArray<2>; + +// Create array for x coordinates +static std::vector MakeCoorVec(int nbOfDataPoints) +{ + std::vector vec; + for (int j = 0; j < nbOfDataPoints; ++j) { + double d = static_cast< double >(j); + vec.push_back({ d / nbOfDataPoints, d / (nbOfDataPoints / 10) }); + } + return vec; +} + +// Create array for weights +std::vector MakeLongLongWeightVec(int nbOfDataPoints) +{ + std::vector vec; + for (int j = 0; j < nbOfDataPoints; ++j) { + long long d = static_cast< long long >(j); + vec.push_back(d); + } + return vec; +} + +// Arrays of coordinates and weights +static std::vector coords = MakeCoorVec(3000000); +std::vector weightsLongLong = MakeLongLongWeightVec(3000000); + +// Histograms with different bin configurations for Fill +ROOT::Experimental::RH2LL hist1LongLong{{10, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist2LongLong{{10, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist3LongLong{{10, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist4LongLong{{100, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist5LongLong{{100, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist6LongLong{{100, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist7LongLong{{1000, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist8LongLong{{1000, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist9LongLong{{1000, 0.1, 1.}, {1000 / 2, 0., 10.}}; + +std::map> histFill = { { 10, { { 5, &hist1LongLong }, { 50, &hist2LongLong }, { 500, &hist3LongLong} } }, + { 100, { { 5, &hist4LongLong }, { 50, &hist5LongLong }, { 500, &hist6LongLong } } }, + { 1000, { { 5, &hist7LongLong }, { 50, &hist8LongLong }, { 500, &hist9LongLong } } } }; + +static void FillHist(int nbOfDataPoints, ROOT::Experimental::RH2LL * hist) +{ + // Fill without weight + for (int i = 0; i < nbOfDataPoints; ++i) { + double d = static_cast< double >(i); + hist->Fill({d / nbOfDataPoints, d / (nbOfDataPoints / 10)}); + } + // Fill with weights + for (int i = 0; i < nbOfDataPoints; ++i) { + double d = static_cast< double >(i); + long long w = static_cast< long long >(i); + hist->Fill({d / nbOfDataPoints, d / (nbOfDataPoints / 10)}, w); + } +} + +// Benchmark for simple Fill on 2D hist +static void BM_RHist_Fill_LongLong(benchmark::State &state) +{ + int nbOfDataPoints = state.range(0); + int nbOfBinsForFirstAxis = state.range(1); + int nbOfBinsForSecondAxis = state.range(2); + + auto hist = histFill[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; + + for (auto _ : state) + FillHist(nbOfDataPoints, hist); +} +BENCHMARK(BM_RHist_Fill_LongLong) -> Apply(FillArguments); + +// Histograms with different bin configurations for FillN +ROOT::Experimental::RH2LL hist11LongLong{{10, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist12LongLong{{10, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist13LongLong{{10, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist14LongLong{{100, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist15LongLong{{100, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist16LongLong{{100, 0.1, 1.}, {1000 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist17LongLong{{1000, 0.1, 1.}, {10 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist18LongLong{{1000, 0.1, 1.}, {100 / 2, 0., 10.}}; +ROOT::Experimental::RH2LL hist19LongLong{{1000, 0.1, 1.}, {1000 / 2, 0., 10.}}; + +std::map> histFillNLongLong = { { 10, { { 5, &hist11LongLong }, { 50, &hist12LongLong }, { 500, &hist13LongLong} } }, + { 100, { { 5, &hist14LongLong }, { 50, &hist15LongLong }, { 500, &hist16LongLong } } }, + { 1000, { { 5, &hist17LongLong }, { 50, &hist18LongLong }, { 500, &hist19LongLong } } } }; + +// Benchmark for simple FillN on 2D hist +static void BM_RHist_FillN_LongLong(benchmark::State &state) +{ + int nbOfDataPoints = state.range(0); + int nbOfBinsForFirstAxis = state.range(1); + int nbOfBinsForSecondAxis = state.range(2); + + auto hist = histFillNLongLong[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; + + for (auto _ : state) { + // FillN with weights + hist->FillN(std::span(&coords[0], nbOfDataPoints), std::span(&weightsLongLong[0], nbOfDataPoints)); + // FillN without weight + hist->FillN(std::span(&coords[0], nbOfDataPoints)); + } +} +BENCHMARK(BM_RHist_FillN_LongLong) -> Apply(FillArguments); + +// // Call main() +// BENCHMARK_MAIN(); diff --git a/root/hist/hist/THistFillBenchmarks.cxx b/root/hist/hist/THistFillBenchmarks.cxx deleted file mode 100644 index db29ace8..00000000 --- a/root/hist/hist/THistFillBenchmarks.cxx +++ /dev/null @@ -1,134 +0,0 @@ -#include "TH2.h" -#include "TH2D.h" - -#include "benchmark/benchmark.h" - -#include -#include - -// Define benchmark arguments -static void FillArguments(benchmark::internal::Benchmark *b) -{ - // Number of data points - for(int i = 3; i <= 3000000; i *= 100) - // Number of bins - for(int j = 10; j <= 1000; j *= 10) - b->Args({i, j, j / 2}); -} - -// Create array for x coordinates -std::vector MakeXCoorVec(int nbOfDataPoints) -{ - std::vector vec; - for (int j = 0; j < nbOfDataPoints; ++j) { - double d = static_cast< double >(j); - vec.push_back(d / nbOfDataPoints); - } - return vec; -} - -// Create array for y coordinates -std::vector MakeYCoorVec(int nbOfDataPoints) -{ - std::vector vec; - for (int j = 0; j < nbOfDataPoints; ++j) { - double d = static_cast< double >(j); - vec.push_back(d / (nbOfDataPoints / 10)); - } - return vec; -} - -// Create array for weights -std::vector MakeWeightVec(int nbOfDataPoints) -{ - std::vector vec; - for (int j = 0; j < nbOfDataPoints; ++j) { - double d = static_cast< double >(j); - vec.push_back(d); - } - return vec; -} - -// Arrays of coordinates and weights -std::vector xCoords = MakeXCoorVec(3000000); -std::vector yCoords = MakeYCoorVec(3000000); -std::vector weights = MakeWeightVec(3000000); - -// Histograms with different bin configurations for Fill -TH2D hist1{"hist1", "", 10, 0.1, 1., 10 / 2, 0., 10.}; -TH2D hist2{"hist2", "", 10, 0.1, 1., 100 / 2, 0., 10.}; -TH2D hist3{"hist3", "", 10, 0.1, 1., 1000 / 2, 0., 10.}; -TH2D hist4{"hist4", "", 100, 0.1, 1., 10 / 2, 0., 10.}; -TH2D hist5{"hist5", "", 100, 0.1, 1., 100 / 2, 0., 10.}; -TH2D hist6{"hist6", "", 100, 0.1, 1., 1000 / 2, 0., 10.}; -TH2D hist7{"hist7", "", 1000, 0.1, 1., 10 / 2, 0., 10.}; -TH2D hist8{"hist8", "", 1000, 0.1, 1., 100 / 2, 0., 10.}; -TH2D hist9{"hist9", "", 1000, 0.1, 1., 1000 / 2, 0., 10.}; - -std::map> histFill = { { 10, { { 5, &hist1 }, { 50, &hist2 }, { 500, &hist3} } }, - { 100, { { 5, &hist4 }, { 50, &hist5 }, { 500, &hist6 } } }, - { 1000, { { 5, &hist7 }, { 50, &hist8 }, { 500, &hist9 } } } }; - -static void FillHist(int nbOfDataPoints, TH2D * hist) -{ - // Fill without weight - for (int i = 0; i < nbOfDataPoints; ++i) { - double d = static_cast< double >(i); - hist->Fill(d / nbOfDataPoints, d / (nbOfDataPoints / 10)); - } - // Fill with weights - for (int i = 0; i < nbOfDataPoints; ++i) { - double d = static_cast< double >(i); - hist->Fill(d / nbOfDataPoints, d / (nbOfDataPoints / 10), d); - } -} - -// Benchmark for simple Fill on 2D hist -static void BM_THist_Fill(benchmark::State &state) -{ - int nbOfDataPoints = state.range(0); - int nbOfBinsForFirstAxis = state.range(1); - int nbOfBinsForSecondAxis = state.range(2); - - auto hist = histFill[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; - - for (auto _ : state) - FillHist(nbOfDataPoints, hist); -} -BENCHMARK(BM_THist_Fill) -> Apply(FillArguments); - -// Histograms with different bin configurations for FillN -TH2D hist11{"hist11", "", 10, 0.1, 1., 10 / 2, 0., 10.}; -TH2D hist12{"hist12", "", 10, 0.1, 1., 100 / 2, 0., 10.}; -TH2D hist13{"hist13", "", 10, 0.1, 1., 1000 / 2, 0., 10.}; -TH2D hist14{"hist14", "", 100, 0.1, 1., 10 / 2, 0., 10.}; -TH2D hist15{"hist15", "", 100, 0.1, 1., 100 / 2, 0., 10.}; -TH2D hist16{"hist16", "", 100, 0.1, 1., 1000 / 2, 0., 10.}; -TH2D hist17{"hist17", "", 1000, 0.1, 1., 10 / 2, 0., 10.}; -TH2D hist18{"hist18", "", 1000, 0.1, 1., 100 / 2, 0., 10.}; -TH2D hist19{"hist19", "", 1000, 0.1, 1., 1000 / 2, 0., 10.}; - -std::map> histFillN = { { 10, { { 5, &hist11 }, { 50, &hist12 }, { 500, &hist13} } }, - { 100, { { 5, &hist14 }, { 50, &hist15 }, { 500, &hist16 } } }, - { 1000, { { 5, &hist17 }, { 50, &hist18 }, { 500, &hist19 } } } }; - -// Benchmark for simple FillN on 2D hist -static void BM_THist_FillN(benchmark::State &state) -{ - int nbOfDataPoints = state.range(0); - int nbOfBinsForFirstAxis = state.range(1); - int nbOfBinsForSecondAxis = state.range(2); - - auto hist = histFillN[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; - - for (auto _ : state) { - // FillN without weight - hist->FillN(nbOfDataPoints, &xCoords[0], &yCoords[0], &weights[0], 1); - // FillN with weights - hist->FillN(nbOfDataPoints, &xCoords[0], &yCoords[0], NULL, 1); - } -} -BENCHMARK(BM_THist_FillN) -> Apply(FillArguments); - -// Call main() -BENCHMARK_MAIN(); diff --git a/root/hist/hist/THistFillDoubleBenchmarks.cxx b/root/hist/hist/THistFillDoubleBenchmarks.cxx new file mode 100644 index 00000000..74dfe981 --- /dev/null +++ b/root/hist/hist/THistFillDoubleBenchmarks.cxx @@ -0,0 +1,134 @@ +#include "TH2.h" +#include "TH2D.h" + +#include "benchmark/benchmark.h" + +#include +#include + +// Define benchmark arguments +static void FillArguments(benchmark::internal::Benchmark *b) +{ + // Number of data points + for(int i = 3; i <= 3000000; i *= 100) + // Number of bins + for(int j = 10; j <= 1000; j *= 10) + b->Args({i, j, j / 2}); +} + +// Create array for x coordinates +static std::vector MakeXCoorVec(int nbOfDataPoints) +{ + std::vector vec; + for (int j = 0; j < nbOfDataPoints; ++j) { + double d = static_cast< double >(j); + vec.push_back(d / nbOfDataPoints); + } + return vec; +} + +// Create array for y coordinates +static std::vector MakeYCoorVec(int nbOfDataPoints) +{ + std::vector vec; + for (int j = 0; j < nbOfDataPoints; ++j) { + double d = static_cast< double >(j); + vec.push_back(d / (nbOfDataPoints / 10)); + } + return vec; +} + +// Create array for weights +std::vector MakeDoubleWeightVec(int nbOfDataPoints) +{ + std::vector vec; + for (int j = 0; j < nbOfDataPoints; ++j) { + double d = static_cast< double >(j); + vec.push_back(d); + } + return vec; +} + +// Arrays of coordinates and weights +static std::vector xCoords = MakeXCoorVec(3000000); +static std::vector yCoords = MakeYCoorVec(3000000); +std::vector weightsDouble = MakeDoubleWeightVec(3000000); + +// Histograms with different bin configurations for Fill +TH2D hist1Double{"hist1Double", "", 10, 0.1, 1., 10 / 2, 0., 10.}; +TH2D hist2Double{"hist2Double", "", 10, 0.1, 1., 100 / 2, 0., 10.}; +TH2D hist3Double{"hist3Double", "", 10, 0.1, 1., 1000 / 2, 0., 10.}; +TH2D hist4Double{"hist4Double", "", 100, 0.1, 1., 10 / 2, 0., 10.}; +TH2D hist5Double{"hist5Double", "", 100, 0.1, 1., 100 / 2, 0., 10.}; +TH2D hist6Double{"hist6Double", "", 100, 0.1, 1., 1000 / 2, 0., 10.}; +TH2D hist7Double{"hist7Double", "", 1000, 0.1, 1., 10 / 2, 0., 10.}; +TH2D hist8Double{"hist8Double", "", 1000, 0.1, 1., 100 / 2, 0., 10.}; +TH2D hist9Double{"hist9Double", "", 1000, 0.1, 1., 1000 / 2, 0., 10.}; + +std::map> histFillDouble = { { 10, { { 5, &hist1Double }, { 50, &hist2Double }, { 500, &hist3Double} } }, + { 100, { { 5, &hist4Double }, { 50, &hist5Double }, { 500, &hist6Double } } }, + { 1000, { { 5, &hist7Double }, { 50, &hist8Double }, { 500, &hist9Double } } } }; + +static void FillHist(int nbOfDataPoints, TH2D * hist) +{ + // Fill without weight + for (int i = 0; i < nbOfDataPoints; ++i) { + double d = static_cast< double >(i); + hist->Fill(d / nbOfDataPoints, d / (nbOfDataPoints / 10)); + } + // Fill with weights + for (int i = 0; i < nbOfDataPoints; ++i) { + double d = static_cast< double >(i); + hist->Fill(d / nbOfDataPoints, d / (nbOfDataPoints / 10), d); + } +} + +// Benchmark for simple Fill on 2D hist +static void BM_THist_Fill_Double(benchmark::State &state) +{ + int nbOfDataPoints = state.range(0); + int nbOfBinsForFirstAxis = state.range(1); + int nbOfBinsForSecondAxis = state.range(2); + + auto hist = histFillDouble[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; + + for (auto _ : state) + FillHist(nbOfDataPoints, hist); +} +BENCHMARK(BM_THist_Fill_Double) -> Apply(FillArguments); + +// Histograms with different bin configurations for FillN +TH2D hist11Double{"hist11Double", "", 10, 0.1, 1., 10 / 2, 0., 10.}; +TH2D hist12Double{"hist12Double", "", 10, 0.1, 1., 100 / 2, 0., 10.}; +TH2D hist13Double{"hist13Double", "", 10, 0.1, 1., 1000 / 2, 0., 10.}; +TH2D hist14Double{"hist14Double", "", 100, 0.1, 1., 10 / 2, 0., 10.}; +TH2D hist15Double{"hist15Double", "", 100, 0.1, 1., 100 / 2, 0., 10.}; +TH2D hist16Double{"hist16Double", "", 100, 0.1, 1., 1000 / 2, 0., 10.}; +TH2D hist17Double{"hist17Double", "", 1000, 0.1, 1., 10 / 2, 0., 10.}; +TH2D hist18Double{"hist18Double", "", 1000, 0.1, 1., 100 / 2, 0., 10.}; +TH2D hist19Double{"hist19Double", "", 1000, 0.1, 1., 1000 / 2, 0., 10.}; + +std::map> histFillNDouble = { { 10, { { 5, &hist11Double }, { 50, &hist12Double }, { 500, &hist13Double} } }, + { 100, { { 5, &hist14Double }, { 50, &hist15Double }, { 500, &hist16Double } } }, + { 1000, { { 5, &hist17Double }, { 50, &hist18Double }, { 500, &hist19Double } } } }; + +// Benchmark for simple FillN on 2D hist +static void BM_THist_FillN_Double(benchmark::State &state) +{ + int nbOfDataPoints = state.range(0); + int nbOfBinsForFirstAxis = state.range(1); + int nbOfBinsForSecondAxis = state.range(2); + + auto hist = histFillNDouble[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; + + for (auto _ : state) { + // FillN without weight + hist->FillN(nbOfDataPoints, &xCoords[0], &yCoords[0], &weightsDouble[0], 1); + // FillN with weights + hist->FillN(nbOfDataPoints, &xCoords[0], &yCoords[0], NULL, 1); + } +} +BENCHMARK(BM_THist_FillN_Double) -> Apply(FillArguments); + +// Call main() +BENCHMARK_MAIN(); diff --git a/root/hist/hist/THistFillFloatBenchmarks.cxx b/root/hist/hist/THistFillFloatBenchmarks.cxx new file mode 100644 index 00000000..e9510386 --- /dev/null +++ b/root/hist/hist/THistFillFloatBenchmarks.cxx @@ -0,0 +1,135 @@ +#include "TH2.h" +#include "TH2F.h" + +#include "benchmark/benchmark.h" + +#include +#include + +// Define benchmark arguments +static void FillArguments(benchmark::internal::Benchmark *b) +{ + // Number of data points + for(int i = 3; i <= 3000000; i *= 100) + // Number of bins + for(int j = 10; j <= 1000; j *= 10) + b->Args({i, j, j / 2}); +} + +// Create array for x coordinates +static std::vector MakeXCoorVec(int nbOfDataPoints) +{ + std::vector vec; + for (int j = 0; j < nbOfDataPoints; ++j) { + double d = static_cast< double >(j); + vec.push_back(d / nbOfDataPoints); + } + return vec; +} + +// Create array for y coordinates +static std::vector MakeYCoorVec(int nbOfDataPoints) +{ + std::vector vec; + for (int j = 0; j < nbOfDataPoints; ++j) { + double d = static_cast< double >(j); + vec.push_back(d / (nbOfDataPoints / 10)); + } + return vec; +} + +// Create array for weights +std::vector MakeFloatWeightVec(int nbOfDataPoints) +{ + std::vector vec; + for (int j = 0; j < nbOfDataPoints; ++j) { + float d = static_cast< float >(j); + vec.push_back(d); + } + return vec; +} + +// Arrays of coordinates and weights +static std::vector xCoords = MakeXCoorVec(3000000); +static std::vector yCoords = MakeYCoorVec(3000000); +std::vector weightsFloat = MakeFloatWeightVec(3000000); + +// Histograms with different bin configurations for Fill +TH2F hist1Float{"hist1Float", "", 10, 0.1, 1., 10 / 2, 0., 10.}; +TH2F hist2Float{"hist2Float", "", 10, 0.1, 1., 100 / 2, 0., 10.}; +TH2F hist3Float{"hist3Float", "", 10, 0.1, 1., 1000 / 2, 0., 10.}; +TH2F hist4Float{"hist4Float", "", 100, 0.1, 1., 10 / 2, 0., 10.}; +TH2F hist5Float{"hist5Float", "", 100, 0.1, 1., 100 / 2, 0., 10.}; +TH2F hist6Float{"hist6Float", "", 100, 0.1, 1., 1000 / 2, 0., 10.}; +TH2F hist7Float{"hist7Float", "", 1000, 0.1, 1., 10 / 2, 0., 10.}; +TH2F hist8Float{"hist8Float", "", 1000, 0.1, 1., 100 / 2, 0., 10.}; +TH2F hist9Float{"hist9Float", "", 1000, 0.1, 1., 1000 / 2, 0., 10.}; + +std::map> histFillFloat = { { 10, { { 5, &hist1Float }, { 50, &hist2Float }, { 500, &hist3Float} } }, + { 100, { { 5, &hist4Float }, { 50, &hist5Float }, { 500, &hist6Float } } }, + { 1000, { { 5, &hist7Float }, { 50, &hist8Float }, { 500, &hist9Float } } } }; + +static void FillHist(int nbOfDataPoints, TH2F * hist) +{ + // Fill without weight + for (int i = 0; i < nbOfDataPoints; ++i) { + double d = static_cast< double >(i); + hist->Fill(d / nbOfDataPoints, d / (nbOfDataPoints / 10)); + } + // Fill with weights + for (int i = 0; i < nbOfDataPoints; ++i) { + double d = static_cast< double >(i); + float w = static_cast< float >(i); + hist->Fill(d / nbOfDataPoints, d / (nbOfDataPoints / 10), w); + } +} + +// Benchmark for simple Fill on 2D hist +static void BM_THist_Fill_Float(benchmark::State &state) +{ + int nbOfDataPoints = state.range(0); + int nbOfBinsForFirstAxis = state.range(1); + int nbOfBinsForSecondAxis = state.range(2); + + auto hist = histFillFloat[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; + + for (auto _ : state) + FillHist(nbOfDataPoints, hist); +} +BENCHMARK(BM_THist_Fill_Float) -> Apply(FillArguments); + +// Histograms with different bin configurations for FillN +TH2F hist11Float{"hist11Float", "", 10, 0.1, 1., 10 / 2, 0., 10.}; +TH2F hist12Float{"hist12Float", "", 10, 0.1, 1., 100 / 2, 0., 10.}; +TH2F hist13Float{"hist13Float", "", 10, 0.1, 1., 1000 / 2, 0., 10.}; +TH2F hist14Float{"hist14Float", "", 100, 0.1, 1., 10 / 2, 0., 10.}; +TH2F hist15Float{"hist15Float", "", 100, 0.1, 1., 100 / 2, 0., 10.}; +TH2F hist16Float{"hist16Float", "", 100, 0.1, 1., 1000 / 2, 0., 10.}; +TH2F hist17Float{"hist17Float", "", 1000, 0.1, 1., 10 / 2, 0., 10.}; +TH2F hist18Float{"hist18Float", "", 1000, 0.1, 1., 100 / 2, 0., 10.}; +TH2F hist19Float{"hist19Float", "", 1000, 0.1, 1., 1000 / 2, 0., 10.}; + +std::map> histFillNFloat = { { 10, { { 5, &hist11Float }, { 50, &hist12Float }, { 500, &hist13Float} } }, + { 100, { { 5, &hist14Float }, { 50, &hist15Float }, { 500, &hist16Float } } }, + { 1000, { { 5, &hist17Float }, { 50, &hist18Float }, { 500, &hist19Float } } } }; + +// Benchmark for simple FillN on 2D hist +static void BM_THist_FillN_Float(benchmark::State &state) +{ + int nbOfDataPoints = state.range(0); + int nbOfBinsForFirstAxis = state.range(1); + int nbOfBinsForSecondAxis = state.range(2); + + auto hist = histFillNFloat[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; + + for (auto _ : state) { + // FillN with weights + hist->FillN(nbOfDataPoints, &xCoords[0], &yCoords[0], (double*) &weightsFloat[0], 1); + // FillN without weight + hist->FillN(nbOfDataPoints, &xCoords[0], &yCoords[0], NULL, 1); + } +} +BENCHMARK(BM_THist_FillN_Float) -> Apply(FillArguments); + +// // Call main() +// BENCHMARK_MAIN(); diff --git a/root/hist/hist/THistFillIntBenchmarks.cxx b/root/hist/hist/THistFillIntBenchmarks.cxx new file mode 100644 index 00000000..14aba0bb --- /dev/null +++ b/root/hist/hist/THistFillIntBenchmarks.cxx @@ -0,0 +1,135 @@ +#include "TH2.h" +#include "TH2I.h" + +#include "benchmark/benchmark.h" + +#include +#include + +// Define benchmark arguments +static void FillArguments(benchmark::internal::Benchmark *b) +{ + // Number of data points + for(int i = 3; i <= 3000000; i *= 100) + // Number of bins + for(int j = 10; j <= 1000; j *= 10) + b->Args({i, j, j / 2}); +} + +// Create array for x coordinates +static std::vector MakeXCoorVec(int nbOfDataPoints) +{ + std::vector vec; + for (int j = 0; j < nbOfDataPoints; ++j) { + double d = static_cast< double >(j); + vec.push_back(d / nbOfDataPoints); + } + return vec; +} + +// Create array for y coordinates +static std::vector MakeYCoorVec(int nbOfDataPoints) +{ + std::vector vec; + for (int j = 0; j < nbOfDataPoints; ++j) { + double d = static_cast< double >(j); + vec.push_back(d / (nbOfDataPoints / 10)); + } + return vec; +} + +// Create array for weights +std::vector MakeIntWeightVec(int nbOfDataPoints) +{ + std::vector vec; + for (int j = 0; j < nbOfDataPoints; ++j) { + int d = static_cast< int >(j); + vec.push_back(d); + } + return vec; +} + +// Arrays of coordinates and weights +static std::vector xCoords = MakeXCoorVec(3000000); +static std::vector yCoords = MakeYCoorVec(3000000); +std::vector weightsInt = MakeIntWeightVec(3000000); + +// Histograms with different bin configurations for Fill +TH2I hist1Int{"hist1Int", "", 10, 0.1, 1., 10 / 2, 0., 10.}; +TH2I hist2Int{"hist2Int", "", 10, 0.1, 1., 100 / 2, 0., 10.}; +TH2I hist3Int{"hist3Int", "", 10, 0.1, 1., 1000 / 2, 0., 10.}; +TH2I hist4Int{"hist4Int", "", 100, 0.1, 1., 10 / 2, 0., 10.}; +TH2I hist5Int{"hist5Int", "", 100, 0.1, 1., 100 / 2, 0., 10.}; +TH2I hist6Int{"hist6Int", "", 100, 0.1, 1., 1000 / 2, 0., 10.}; +TH2I hist7Int{"hist7Int", "", 1000, 0.1, 1., 10 / 2, 0., 10.}; +TH2I hist8Int{"hist8Int", "", 1000, 0.1, 1., 100 / 2, 0., 10.}; +TH2I hist9Int{"hist9Int", "", 1000, 0.1, 1., 1000 / 2, 0., 10.}; + +std::map> histFillInt = { { 10, { { 5, &hist1Int }, { 50, &hist2Int }, { 500, &hist3Int} } }, + { 100, { { 5, &hist4Int }, { 50, &hist5Int }, { 500, &hist6Int } } }, + { 1000, { { 5, &hist7Int }, { 50, &hist8Int }, { 500, &hist9Int } } } }; + +static void FillHist(int nbOfDataPoints, TH2I * hist) +{ + // Fill without weight + for (int i = 0; i < nbOfDataPoints; ++i) { + double d = static_cast< double >(i); + hist->Fill(d / nbOfDataPoints, d / (nbOfDataPoints / 10)); + } + // Fill with weights + for (int i = 0; i < nbOfDataPoints; ++i) { + double d = static_cast< double >(i); + int w = static_cast< int >(i); + hist->Fill(d / nbOfDataPoints, d / (nbOfDataPoints / 10), w); + } +} + +// Benchmark for simple Fill on 2D hist +static void BM_THist_Fill_Int(benchmark::State &state) +{ + int nbOfDataPoints = state.range(0); + int nbOfBinsForFirstAxis = state.range(1); + int nbOfBinsForSecondAxis = state.range(2); + + auto hist = histFillInt[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; + + for (auto _ : state) + FillHist(nbOfDataPoints, hist); +} +BENCHMARK(BM_THist_Fill_Int) -> Apply(FillArguments); + +// Histograms with different bin configurations for FillN +TH2I hist11Int{"hist11Int", "", 10, 0.1, 1., 10 / 2, 0., 10.}; +TH2I hist12Int{"hist12Int", "", 10, 0.1, 1., 100 / 2, 0., 10.}; +TH2I hist13Int{"hist13Int", "", 10, 0.1, 1., 1000 / 2, 0., 10.}; +TH2I hist14Int{"hist14Int", "", 100, 0.1, 1., 10 / 2, 0., 10.}; +TH2I hist15Int{"hist15Int", "", 100, 0.1, 1., 100 / 2, 0., 10.}; +TH2I hist16Int{"hist16Int", "", 100, 0.1, 1., 1000 / 2, 0., 10.}; +TH2I hist17Int{"hist17Int", "", 1000, 0.1, 1., 10 / 2, 0., 10.}; +TH2I hist18Int{"hist18Int", "", 1000, 0.1, 1., 100 / 2, 0., 10.}; +TH2I hist19Int{"hist19Int", "", 1000, 0.1, 1., 1000 / 2, 0., 10.}; + +std::map> histFillNInt = { { 10, { { 5, &hist11Int }, { 50, &hist12Int }, { 500, &hist13Int} } }, + { 100, { { 5, &hist14Int }, { 50, &hist15Int }, { 500, &hist16Int } } }, + { 1000, { { 5, &hist17Int }, { 50, &hist18Int }, { 500, &hist19Int } } } }; + +// Benchmark for simple FillN on 2D hist +static void BM_THist_FillN_Int(benchmark::State &state) +{ + int nbOfDataPoints = state.range(0); + int nbOfBinsForFirstAxis = state.range(1); + int nbOfBinsForSecondAxis = state.range(2); + + auto hist = histFillNInt[nbOfBinsForFirstAxis][nbOfBinsForSecondAxis]; + + for (auto _ : state) { + // FillN with weights + hist->FillN(nbOfDataPoints, &xCoords[0], &yCoords[0], (double*) &weightsInt[0], 1); + // FillN without weight + hist->FillN(nbOfDataPoints, &xCoords[0], &yCoords[0], NULL, 1); + } +} +BENCHMARK(BM_THist_FillN_Int) -> Apply(FillArguments); + +// // Call main() +// BENCHMARK_MAIN();