From 696e76f4b78ec8efddc7ecd8b70fba5cfc608ce1 Mon Sep 17 00:00:00 2001 From: Henry Fredrick Schreiner Date: Tue, 17 Dec 2019 17:55:15 -0500 Subject: [PATCH] Use integer fill for integer storages (avoid a conversion to double) --- boost_histogram/_internal/hist.py | 7 +++--- include/fill.hpp | 37 ++++++++++++++++++------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/boost_histogram/_internal/hist.py b/boost_histogram/_internal/hist.py index d6aa6ad0..0db4896b 100644 --- a/boost_histogram/_internal/hist.py +++ b/boost_histogram/_internal/hist.py @@ -184,11 +184,10 @@ def fill(self, *args, **kwargs): ---------- *args : Union[Array[float], Array[int], Array[str], float, int, str] Provide one value or array per dimension. - weight : List[Union[Array[float], Array[int], Array[str], float, int, str]]] - Provide weights (only if the histogram storage supports it) - sample : List[Union[Array[float], Array[int], Array[str], float, int, str]]] + weight : List[Union[Array[float], Array[int], float, int]]] + Provide weights (float only if the histogram storage supports it) + sample : List[Union[Array[float], float]]] Provide samples (only if the histogram storage supports it) - """ self._hist.fill(*args, **kwargs) diff --git a/include/fill.hpp b/include/fill.hpp index 621b1ee3..a3d91158 100644 --- a/include/fill.hpp +++ b/include/fill.hpp @@ -101,8 +101,8 @@ using arg_t = variant::variant, int, c_array_t, std::string>; - -using weight_t = variant::variant>; +template +using weight_t = variant::variant>; inline auto get_vargs(const vector_axis_variant& axes, const py::args& args) { if(args.size() != axes.size()) @@ -131,25 +131,26 @@ inline auto get_vargs(const vector_axis_variant& axes, const py::args& args) { return vargs; } -inline auto get_weight(py::kwargs& kwargs) { +template +auto get_weight(py::kwargs& kwargs) { // default constructed as monostate to indicate absence of weight - variant::variant> weight; + weight_t weight; auto w = optional_arg(kwargs, "weight"); if(!w.is_none()) { - if(is_value(w)) - weight = py::cast(w); + if(is_value(w)) + weight = py::cast(w); else - weight = py::cast>(w); + weight = py::cast>(w); } return weight; } // for accumulators that accept a weight -template +template void fill_impl(bh::detail::accumulator_traits_holder, Histogram& h, const VArgs& vargs, - const weight_t& weight, + const weight_t& weight, py::kwargs& kwargs) { finalize_args(kwargs); @@ -162,11 +163,11 @@ void fill_impl(bh::detail::accumulator_traits_holder, } // for accumulators that accept a weight and a double -template +template void fill_impl(bh::detail::accumulator_traits_holder, Histogram& h, const VArgs& vargs, - const weight_t& weight, + const weight_t& weight, py::kwargs& kwargs) { auto s = required_arg(kwargs, "sample"); finalize_args(kwargs); @@ -191,10 +192,14 @@ void fill_impl(bh::detail::accumulator_traits_holder, template Histogram& fill(Histogram& self, py::args args, py::kwargs kwargs) { using value_type = typename Histogram::value_type; - detail::fill_impl(bh::detail::accumulator_traits{}, - self, - detail::get_vargs(bh::unsafe_access::axes(self), args), - detail::get_weight(kwargs), - kwargs); + using weight_type + = boost::mp11::mp_if_c::value, int, double>; + + detail::fill_impl( + bh::detail::accumulator_traits{}, + self, + detail::get_vargs(bh::unsafe_access::axes(self), args), + detail::get_weight(kwargs), + kwargs); return self; }