From 0cc7f02c823dbf177d42227bbaf66ee24b36eb84 Mon Sep 17 00:00:00 2001 From: Hans Dembinski Date: Sun, 17 Jul 2016 12:03:57 -0400 Subject: [PATCH] bug fix in speed test, and even faster binning --- README.md | 8 ++++---- include/boost/histogram/axis.hpp | 26 ++++++++++++++++++++------ test/check/speed_cpp.cpp | 2 +- test/check/speed_root.cpp | 2 +- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 1edc09ff..5f2dba35 100644 --- a/README.md +++ b/README.md @@ -165,10 +165,10 @@ distribution uniform dimension 1D 3D 6D 1D 3D 6D ========================================== ======= ======= ======= ======= ======= ======= No. of fills 12M 4M 2M 12M 4M 2M -C++: ROOT [t/s] 0.127 0.199 0.185 0.168 0.143 0.179 -C++: boost/static_storage [t/s] 0.073 0.160 0.178 0.159 0.182 0.187 -Py: numpy [t/s] 0.825 0.727 0.436 0.824 0.426 0.401 -Py: boost [t/s] 0.209 0.229 0.192 0.207 0.194 0.168 +C++: ROOT [t/s] 0.13 0.19 0.18 0.14 0.18 0.20 +C++: boost/static_storage [t/s] 0.07 0.16 0.18 0.08 0.15 0.19 +Py: numpy [t/s] 0.83 0.73 0.44 0.82 0.43 0.40 +Py: boost [t/s] 0.21 0.23 0.19 0.21 0.19 0.17 ========================================== ======= ======= ======= ======= ======= ======= ``` diff --git a/include/boost/histogram/axis.hpp b/include/boost/histogram/axis.hpp index 62570efc..ae1ec3f2 100644 --- a/include/boost/histogram/axis.hpp +++ b/include/boost/histogram/axis.hpp @@ -7,6 +7,7 @@ #ifndef _BOOST_HISTOGRAM_AXIS_HPP_ #define _BOOST_HISTOGRAM_AXIS_HPP_ +#include #include #include #include @@ -25,7 +26,7 @@ namespace boost { namespace histogram { -/// common base class for most axes +/// Common base class for most axes class axis_base { public: ///Returns the number of bins. @@ -60,7 +61,7 @@ private: friend void serialize(Archive& ar, axis_base & base, unsigned version); }; -// mixin for real-valued axes +/// Mixin for real-valued axes template class real_axis { public: @@ -79,7 +80,12 @@ public: } }; -///An axis for real-valued data and bins of equal width. Binning is a O(1) operation. +/** Axis for binning real-valued data into equidistant bins + * + * This is the simplest and common binning strategy. The code + * was optimized with a profiled benchmark. + * Binning is a O(1) operation. + */ class regular_axis: public axis_base, public real_axis { public: /** Constructor @@ -107,11 +113,14 @@ public: regular_axis& operator=(const regular_axis&) = default; regular_axis& operator=(regular_axis&&) = default; - ///Returns the bin index for the passed argument (optimized code). + /// Returns the bin index for the passed argument (optimized code). inline int index(double x) const { const double z = (x - min_) / delta_; - return std::signbit(z) ? -1 : z < bins() ? static_cast(z) : bins(); + const int i = static_cast(z); + if (i > bins()) + return bins(); + return z >= 0.0 ? i : -1; } double operator[](int idx) const @@ -138,7 +147,12 @@ private: friend void serialize(Archive& ar, regular_axis & axis ,unsigned version); }; -///An axis for real-valued angles. There are no overflow/underflow bins for this axis, since the axis is circular and wraps around after :math:`2 \pi`. Binning is a O(1) operation. +/** Axis for real-valued angles + * + * There are no overflow/underflow bins for this axis, + * since the axis is circular and wraps around after :math:`2 \pi`. + * Binning is a O(1) operation. + */ class polar_axis: public axis_base, public real_axis { public: /** Constructor diff --git a/test/check/speed_cpp.cpp b/test/check/speed_cpp.cpp index 41296a06..7cadd70b 100644 --- a/test/check/speed_cpp.cpp +++ b/test/check/speed_cpp.cpp @@ -20,7 +20,7 @@ std::vector random_array(unsigned n, int type) { std::vector result(n); std::default_random_engine gen(1); if (type) { // type == 1 - std::normal_distribution<> d(0.0, 0.3); + std::normal_distribution<> d(0.5, 0.3); for (auto& x : result) x = d(gen); } diff --git a/test/check/speed_root.cpp b/test/check/speed_root.cpp index 6290a1fb..772b9ea9 100644 --- a/test/check/speed_root.cpp +++ b/test/check/speed_root.cpp @@ -19,7 +19,7 @@ std::vector random_array(unsigned n, int type) { std::vector result(n); std::default_random_engine gen(1); if (type) { // type == 1 - std::normal_distribution<> d(0.0, 0.3); + std::normal_distribution<> d(0.5, 0.3); for (auto& x : result) x = d(gen); }