@@ -84,41 +84,20 @@ using HistPtr = std::variant<std::shared_ptr<THn>, std::shared_ptr<THnSparse>, s
8484constexpr double VARIABLE_WIDTH = 0 .;
8585
8686struct AxisSpec {
87- AxisSpec (std::vector<double > binEdges_, std::optional<std::string> title_ = std::nullopt , std::optional<std::string> name_ = std::nullopt )
88- : nBins(std::nullopt ),
89- binEdges (std::move(binEdges_)),
90- title(std::move(title_)),
91- name(std::move(name_))
92- {
93- }
94-
95- AxisSpec (int nBins_, double binMin_, double binMax_, std::optional<std::string> title_ = std::nullopt , std::optional<std::string> name_ = std::nullopt )
96- : nBins(nBins_),
97- binEdges({binMin_, binMax_}),
98- title(std::move(title_)),
99- name(std::move(name_))
100- {
101- if (binMin_ > binMax_) {
102- LOG (fatal) << " Defined ill-defined axis" ;
103- }
104- }
87+ // Defined out of line in HistogramSpec.cxx on purpose. These run once per
88+ // histogram at init() time, so inlining them buys nothing at runtime, while
89+ // a task that books a few hundred histograms in one init() pays for every
90+ // expansion: each one materialises a std::vector<double> and two
91+ // std::optional<std::string> at the call site, with the matching destructor
92+ // and exception-unwind paths. Under -g that also means a debug record per
93+ // temporary, which is what makes the register allocator's rewrite pass go
94+ // superlinear on such functions.
95+ AxisSpec (std::vector<double > binEdges_, std::optional<std::string> title_ = std::nullopt , std::optional<std::string> name_ = std::nullopt );
96+
97+ AxisSpec (int nBins_, double binMin_, double binMax_, std::optional<std::string> title_ = std::nullopt , std::optional<std::string> name_ = std::nullopt );
10598
10699 // first entry is assumed to be the number of bins; in case of variable size binning it must be set to zero
107- AxisSpec (ConfigurableAxis binEdges_, std::optional<std::string> title_ = std::nullopt , std::optional<std::string> name_ = std::nullopt )
108- : nBins(std::nullopt ),
109- binEdges(std::vector<double >(binEdges_)),
110- title(std::move(title_)),
111- name(std::move(name_))
112- {
113- if (binEdges.empty ()) {
114- return ;
115- }
116- if (binEdges[0 ] != VARIABLE_WIDTH ) {
117- nBins = static_cast <int >(binEdges[0 ]);
118- binEdges.resize (3 ); // nBins, lowerBound, upperBound, disregard whatever else is stored in vecotr
119- }
120- binEdges.erase (binEdges.begin ()); // remove first entry that we assume to be number of bins
121- }
100+ AxisSpec (ConfigurableAxis binEdges_, std::optional<std::string> title_ = std::nullopt , std::optional<std::string> name_ = std::nullopt );
122101
123102 [[nodiscard]] long getNbins () const ;
124103
@@ -138,12 +117,8 @@ struct AxisSpec {
138117 */
139118// **************************************************************************************************
140119struct HistogramConfigSpec {
141- HistogramConfigSpec (HistType type_, std::vector<AxisSpec> axes_, uint8_t nSteps_ = 1 )
142- : type(type_),
143- axes (std::move(axes_)),
144- nSteps(nSteps_)
145- {
146- }
120+ // Out of line for the same reason as the AxisSpec constructors above.
121+ HistogramConfigSpec (HistType type_, std::vector<AxisSpec> axes_, uint8_t nSteps_ = 1 );
147122 HistogramConfigSpec () = default ;
148123 HistogramConfigSpec (HistogramConfigSpec const & other) = default ;
149124 HistogramConfigSpec (HistogramConfigSpec&& other) = default ;
0 commit comments