Logo ROOT  
Reference Guide
histspeedtest.cxx
Go to the documentation of this file.
1 /// \file histspeedtest.cxx
2 ///
3 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
4 /// is welcome!
5 /// \author Axel Naumann <axel@cern.ch>
6 
7 #include "TRandom3.h"
8 #include <vector>
9 #include <chrono>
10 #include <iostream>
11 
12 #include "TH1.h"
13 #include "TH2.h"
14 #include "TH3.h"
15 
16 #include "ROOT/RHist.hxx"
18 
19 using namespace ROOT;
20 using namespace std;
21 
22 constexpr unsigned short gRepeat = 2;
23 
24 /* DataTypes:
25 
26  THistDataContent
27  THistDataUncertainty
28  THistDataMomentUncert
29  THistDataRuntime
30 and
31  MyTHistDataNoStat
32  MyTHistDataContent
33  MyTHistDataMomentUncert
34 
35  /opt/build/root_builds/rootcling.cmake/include/ROOT/THistBinIter.h:53:50: error: no member named 'GetUncertainty' in
36 'ROOT::Experimental::THistDataContent<2, double, ROOT::Experimental::THistDataDefaultStorage>::TBinStat<double>' auto
37 GetUncertainty() const { return GetStat().GetUncertainty(); }
38 
39  new ones (STATCLASSES)
40 
41  THistStatContent
42  THistStatUncertainty
43  THistStatTotalSumOfWeights
44  THistStatTotalSumOfSquaredWeights
45  THistDataMomentUncert
46 
47 
48  */
49 
50 #ifndef STATCLASSES
51 #define STATCLASSES Experimental::RHistStatContent, Experimental::RHistStatUncertainty
52 #endif
53 
54 struct Timer {
55  using TimePoint_t = decltype(std::chrono::high_resolution_clock::now());
56 
57  const char *fTitle;
58  size_t fCount;
59  TimePoint_t fStart;
60 
61  Timer(const char *title, size_t count)
62  : fTitle(title), fCount(count), fStart(std::chrono::high_resolution_clock::now())
63  {}
64 
65  ~Timer()
66  {
67  using namespace std::chrono;
68  auto end = high_resolution_clock::now();
69  duration<double> time_span = duration_cast<duration<double>>(end - fStart);
70  // std::cout << fCount << " * " << fTitle << ": " << time_span.count() << " seconds \n";
71  // std::cout << fCount << " * " << fTitle << ": " << fCount / (1e6) / time_span.count()
72  // << " millions per seconds\n";
73  std::cout << fCount << " * " << fTitle << ": " << time_span.count() << " seconds, \t";
74  std::cout << fCount / (1e6) / time_span.count() << " millions per seconds \n";
75  }
76 };
77 
78 constexpr UInt_t gStride = 32; // TH1::GetDefaultBufferSize()
79 
80 struct BinEdges {
81  static constexpr size_t fNBinsX = 4;
82  static constexpr size_t fNBinsY = 5;
83  double fXBins[4];
84  double fYBins[5];
85 
86  BinEdges(double minValue, double maxValue)
87  {
88  if (maxValue < minValue)
89  swap(minValue, maxValue);
90  double range = maxValue - minValue;
91 
92  double x[fNBinsX] = {0., 0.1, 0.3, 1.};
93  double y[fNBinsY] = {0., 0.1, 0.2, 0.3, 1.};
94 
95  for (size_t i = 0; i < fNBinsX; ++i)
96  fXBins[i] = minValue + range * x[i];
97  for (size_t i = 0; i < fNBinsY; ++i)
98  fYBins[i] = minValue + range * y[i];
99  }
100 
101  using AConf_t = Experimental::RAxisConfig;
102 
103  AConf_t GetConfigX() const { return AConf_t(std::span<const double>(fXBins).to_vector()); }
104  AConf_t GetConfigY() const { return AConf_t(std::span<const double>(fYBins).to_vector()); }
105 };
106 
107 template <typename T>
108 void GenerateInput(std::vector<T> &numbers, double minVal, double maxVal, UInt_t seed)
109 {
110  Timer t("GenerateInput", numbers.size());
111  if (minVal > maxVal) {
112  std::swap(minVal, maxVal);
113  }
114  T range = maxVal - minVal;
115  TRandom3 r(seed);
116  size_t len = numbers.size();
117  for (auto c = numbers.begin(); c != numbers.end(); ++c) {
118  *c = minVal + range * r.Rndm();
119  }
120 }
121 
122 std::string
124 {
125  std::string result =
126  std::string(version) + " " + std::string(histname) + " " + std::string(title) + " [" + std::string(axis) + "]";
127  return result;
128 }
129 
130 template <int dim, typename type>
131 const char *GetHist();
132 
133 template <>
134 const char *GetHist<2, double>()
135 {
136  return "2D";
137 };
138 template <>
139 const char *GetHist<2, float>()
140 {
141  return "2F";
142 };
143 
144 template <>
145 const char *GetHist<1, double>()
146 {
147  return "1D";
148 };
149 template <>
150 const char *GetHist<1, float>()
151 {
152  return "1F";
153 };
154 
155 namespace R7 {
156 const char *gVersion = "R7";
157 
158 template <typename T, unsigned short kNDim>
159 struct Dim;
160 
161 template <typename T>
162 struct Dim<T, 2> {
163 
164  constexpr static unsigned short kNDim = 2;
166 
167  using FillFunc_t = std::add_pointer_t<long(ExpTH2 &hist, std::vector<double> &input, std::string_view type)>;
168 
169  struct EE {
170  static constexpr const char *const gType = "regular bin size ";
171 
172  template <FillFunc_t filler>
173  static long Execute(std::vector<double> &input, double minVal, double maxVal)
174  {
175 
176  ExpTH2 hist({100, minVal, maxVal}, {5, minVal, maxVal});
177  return filler(hist, input, gType);
178  }
179  };
180 
181  struct II {
182  static constexpr const char *const gType = "irregular bin size";
183 
184  template <FillFunc_t filler>
185  static long Execute(std::vector<double> &input, double minVal, double maxVal)
186  {
187 
188  BinEdges edges(minVal, maxVal);
189  ExpTH2 hist(edges.GetConfigX(), edges.GetConfigY());
190  return filler(hist, input, gType);
191  }
192  };
193 
194  inline static long fillN(ExpTH2 &hist, std::vector<double> &input, std::string_view gType)
195  {
196 
197  using array_t = Experimental::Hist::RCoordArray<2>;
198  array_t *values = (array_t *)(&input[0]);
199  constexpr size_t stride = gStride;
200 
201  std::string title = MakeTitle(gVersion, GetHist<kNDim, T>(), "fills N (stride 32)", gType);
202  {
203  Timer t(title.c_str(), input.size() / 2);
204  for (size_t i = 0; i < (input.size() - (stride * 2 - 1)); i += (stride * 2), values += 32) {
205  std::span<array_t> coords(values, 32);
206  hist.FillN(coords);
207  }
208  }
209  return hist.GetNDim();
210  }
211 
212  inline static long fillBuffered(ExpTH2 &hist, std::vector<double> &input, std::string_view gType)
213  {
215  std::string title = MakeTitle(gVersion, GetHist<kNDim, T>(), "fills (buffered) ", gType);
216  {
217  Timer t(title.c_str(), input.size() / 2);
218  for (size_t i = 0; i < input.size() - 1; i += 2)
219  filler.Fill({input[i], input[i + 1]});
220  }
221  return hist.GetNDim();
222  }
223 
224  inline static long fill(ExpTH2 &hist, std::vector<double> &input, std::string_view gType)
225  {
226  std::string title = MakeTitle(gVersion, GetHist<kNDim, T>(), "fills ", gType);
227  {
228  Timer t(title.c_str(), input.size() / 2);
229  for (size_t i = 0; i < input.size() - 1; i += 2)
230  hist.Fill({input[i], input[i + 1]});
231  }
232  return hist.GetNDim();
233  }
234 }; // DimD
235 
236 template <typename T>
237 struct Dim<T, 1> {
238 
239  constexpr static unsigned short kNDim = 1;
241 
242  using FillFunc_t = std::add_pointer_t<long(ExpTH1 &hist, std::vector<double> &input, std::string_view type)>;
243 
244  struct EE {
245  static constexpr const char *const gType = "regular bin size ";
246 
247  template <FillFunc_t filler>
248  static long Execute(std::vector<double> &input, double minVal, double maxVal)
249  {
250  long result = 0;
251  for (unsigned short i = 0; i < gRepeat; ++i) {
252  ExpTH1 hist({100, minVal, maxVal});
253  result += filler(hist, input, gType);
254  }
255  return result;
256  }
257  };
258 
259  struct II {
260  static constexpr const char *const gType = "irregular bin size";
261 
262  template <FillFunc_t filler>
263  static long Execute(std::vector<double> &input, double minVal, double maxVal)
264  {
265 
266  long result = 0;
267  BinEdges edges(minVal, maxVal);
268  for (unsigned short i = 0; i < gRepeat; ++i) {
269  ExpTH1 hist(edges.GetConfigX());
270  result += filler(hist, input, gType);
271  }
272  return result;
273  }
274  };
275 
276  inline static long fillN(ExpTH1 &hist, std::vector<double> &input, std::string_view gType)
277  {
278 
279  using array_t = Experimental::Hist::RCoordArray<1>;
280  array_t *values = (array_t *)(&input[0]);
281  constexpr size_t stride = gStride;
282 
283  std::string title = MakeTitle(gVersion, GetHist<kNDim, T>(), "fills N (stride 32)", gType);
284  {
285  Timer t(title.c_str(), input.size());
286  for (size_t i = 0; i < (input.size() - (stride - 1)); i += (stride), values += 32) {
287  std::span<array_t> coords(values, 32);
288  hist.FillN(coords);
289  }
290  }
291  return hist.GetNDim();
292  }
293 
294  inline static long fillBuffered(ExpTH1 &hist, std::vector<double> &input, std::string_view gType)
295  {
297  std::string title = MakeTitle(gVersion, GetHist<kNDim, T>(), "fills (buffered) ", gType);
298  {
299  Timer t(title.c_str(), input.size());
300  for (size_t i = 0; i < input.size(); ++i)
301  filler.Fill({input[i]});
302  }
303  return hist.GetNDim();
304  }
305 
306  inline static long fill(ExpTH1 &hist, std::vector<double> &input, std::string_view gType)
307  {
308  std::string title = MakeTitle(gVersion, GetHist<kNDim, T>(), "fills ", gType);
309  {
310  Timer t(title.c_str(), input.size());
311  for (size_t i = 0; i < input.size(); ++i)
312  hist.Fill({input[i]});
313  }
314  return hist.GetNDim();
315  }
316 }; // Dim1
317 
318 } // namespace R7
319 
320 namespace R6 {
321 const char *gVersion = "R6";
322 
323 template <int ndim, typename T>
324 struct Redirect;
325 template <>
326 struct Redirect<2, float> {
327  using HistType_t = TH2F;
328 };
329 template <>
330 struct Redirect<2, double> {
331  using HistType_t = TH2D;
332 };
333 template <>
334 struct Redirect<1, float> {
335  using HistType_t = TH1F;
336 };
337 template <>
338 struct Redirect<1, double> {
339  using HistType_t = TH1D;
340 };
341 
342 template <typename T, int kNDim>
343 struct Dim;
344 
345 template <typename T>
346 struct Dim<T, 2> {
347 
348  constexpr static unsigned short kNDim = 2;
349  using HistType_t = typename Redirect<kNDim, T>::HistType_t;
350 
351  using FillFunc_t = std::add_pointer_t<long(HistType_t &hist, std::vector<double> &input, std::string_view type)>;
352 
353  struct EE {
354 
355  static constexpr const char *const gType = "regular bin size ";
356 
357  template <FillFunc_t filler>
358  static long Execute(std::vector<double> &input, double minVal, double maxVal)
359  {
360 
361  long result = 0;
362  for (unsigned short i = 0; i < gRepeat; ++i) {
363  HistType_t hist("a", "a hist", 100, minVal, maxVal, 5, minVal, maxVal);
364  result += filler(hist, input, gType);
365  }
366  return result;
367  }
368  };
369 
370  struct II {
371 
372  static constexpr const char *const gType = "irregular bin size";
373 
374  template <FillFunc_t filler>
375  static long Execute(std::vector<double> &input, double minVal, double maxVal)
376  {
377  long result = 0;
378  BinEdges edges(minVal, maxVal);
379  for (unsigned short i = 0; i < gRepeat; ++i) {
380  HistType_t hist("a", "a hist", edges.fNBinsX - 1, edges.fXBins, edges.fNBinsY - 1, edges.fYBins);
381  result += filler(hist, input, gType);
382  }
383  return result;
384  }
385  };
386 
387  static long fillBuffered(HistType_t &hist, std::vector<double> &input, std::string_view gType)
388  {
389  std::string title = MakeTitle(gVersion, GetHist<kNDim, T>(), "fills (buffered) ", gType);
390  hist.SetBuffer(TH1::GetDefaultBufferSize());
391  {
392  // Timer t("R6 2D fills [regular bins size]",input.size()/2);
393  Timer t(title.c_str(), input.size() / 2);
394  for (size_t i = 0; i < input.size() - 1; i += 2)
395  hist.Fill(input[i], input[i + 1]);
396  }
397  return (long)hist.GetEntries();
398  }
399 
400  static long fillN(HistType_t &hist, std::vector<double> &input, std::string_view gType)
401  {
402  std::string title = MakeTitle(gVersion, GetHist<kNDim, T>(), "fills N (stride 32)", gType);
403  constexpr size_t stride = gStride;
404  {
405  // Timer t("R6 2D fills [regular bins size]",input.size()/2);
406  Timer t(title.c_str(), input.size() / 2);
407  for (size_t i = 0; i < (input.size() - (stride * 2 - 1)); i += (stride * 2))
408  hist.FillN(gStride, &(input[i]), &(input[i + gStride]), nullptr);
409  }
410  return (long)hist.GetEntries();
411  }
412 
413  static long fill(HistType_t &hist, std::vector<double> &input, std::string_view gType)
414  {
415  std::string title = MakeTitle(gVersion, GetHist<kNDim, T>(), "fills ", gType);
416  {
417  // Timer t("R6 2D fills [regular bins size]",input.size()/2);
418  Timer t(title.c_str(), input.size() / 2);
419  for (size_t i = 0; i < input.size() - 1; i += 2)
420  hist.Fill(input[i], input[i + 1]);
421  }
422  return (long)hist.GetEntries();
423  }
424 }; // Dim
425 
426 template <typename T>
427 struct Dim<T, 1> {
428 
429  constexpr static unsigned short kNDim = 1;
430  using HistType_t = typename Redirect<kNDim, T>::HistType_t;
431 
432  using FillFunc_t = std::add_pointer_t<long(HistType_t &hist, std::vector<double> &input, std::string_view type)>;
433 
434  struct EE {
435 
436  static constexpr const char *const gType = "regular bin size ";
437 
438  template <FillFunc_t filler>
439  static long Execute(std::vector<double> &input, double minVal, double maxVal)
440  {
441 
442  long result = 0;
443  for (unsigned short i = 0; i < gRepeat; ++i) {
444  HistType_t hist("a", "a hist", 100, minVal, maxVal);
445  result += filler(hist, input, gType);
446  }
447  return result;
448  }
449  };
450 
451  struct II {
452 
453  static constexpr const char *const gType = "irregular bin size";
454 
455  template <FillFunc_t filler>
456  static long Execute(std::vector<double> &input, double minVal, double maxVal)
457  {
458  long result = 0;
459  BinEdges edges(minVal, maxVal);
460  for (unsigned short i = 0; i < gRepeat; ++i) {
461  HistType_t hist("a", "a hist", edges.fNBinsX - 1, edges.fXBins);
462  result += filler(hist, input, gType);
463  }
464  return result;
465  }
466  };
467 
468  static long fillBuffered(HistType_t &hist, std::vector<double> &input, std::string_view gType)
469  {
470  std::string title = MakeTitle(gVersion, GetHist<kNDim, T>(), "fills (buffered) ", gType);
471  hist.SetBuffer(TH1::GetDefaultBufferSize());
472  {
473  // Timer t("R6 2D fills [regular bins size]",input.size()/2);
474  Timer t(title.c_str(), input.size());
475  for (size_t i = 0; i < input.size() - 1; ++i)
476  hist.Fill(input[i]);
477  }
478  return (long)hist.GetEntries();
479  }
480 
481  static long fillN(HistType_t &hist, std::vector<double> &input, std::string_view gType)
482  {
483  std::string title = MakeTitle(gVersion, GetHist<kNDim, T>(), "fills N (stride 32)", gType);
484  constexpr size_t stride = gStride;
485  {
486  // Timer t("R6 2D fills [regular bins size]",input.size()/2);
487  Timer t(title.c_str(), input.size());
488  for (size_t i = 0; i < (input.size() - (stride - 1)); i += (stride))
489  hist.FillN(gStride, &(input[i]), nullptr);
490  }
491  return (long)hist.GetEntries();
492  }
493 
494  static long fill(HistType_t &hist, std::vector<double> &input, std::string_view gType)
495  {
496  std::string title = MakeTitle(gVersion, GetHist<kNDim, T>(), "fills ", gType);
497  {
498  // Timer t("R6 2D fills [regular bins size]",input.size()/2);
499  Timer t(title.c_str(), input.size());
500  for (size_t i = 0; i < input.size(); ++i)
501  hist.Fill(input[i]);
502  }
503  return (long)hist.GetEntries();
504  }
505 }; // Dim1
506 } // namespace R6
507 
508 template <typename T, unsigned short kNDim>
509 void speedtest(size_t count = (size_t)(1e6));
510 
511 template <>
512 void speedtest<double, 2>(size_t count)
513 {
514  using DataType_t = double;
515  static constexpr unsigned short kNDim = 2;
516 
518 
519  std::vector<double> input; // (count);
520  input.resize(count);
521 
522  double minVal = -5.0;
523  double maxVal = +5.0;
524  GenerateInput(input, minVal, maxVal, 0);
525 
526  // Make sure we have some overflow.
527  minVal *= 0.9;
528  maxVal *= 0.9;
529 
530  cout << '\n';
531 
532  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
533  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
534  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
535  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
536  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
537  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
538 
539  cout << '\n';
540 
541  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
542  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
543  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
544  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
545  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
546  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
547 
548  cout << '\n';
549 
550  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
551  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
552  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
553  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
554  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
555  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
556 
557  cout << '\n';
558 
559  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
560  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
561  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
562  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
563  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
564  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
565 
566  cout << '\n';
567 }
568 
569 // these are copy/paste to work around failure to properly instantiate the template :(
570 
571 template <>
572 void speedtest<float, 2>(size_t count)
573 {
574  using DataType_t = float;
575  constexpr unsigned short kNDim = 2;
576 
578 
579  std::vector<double> input; // (count);
580  input.resize(count);
581 
582  double minVal = -5.0;
583  double maxVal = +5.0;
584  GenerateInput(input, minVal, maxVal, 0);
585 
586  // Make sure we have some overflow.
587  minVal *= 0.9;
588  maxVal *= 0.9;
589 
590  cout << '\n';
591 
592  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
593  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
594  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
595  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
596  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
597  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
598 
599  cout << '\n';
600 
601  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
602  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
603  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
604  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
605  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
606  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
607 
608  cout << '\n';
609 
610  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
611  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
612  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
613  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
614  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
615  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
616 
617  cout << '\n';
618 
619  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
620  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
621  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
622  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
623  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
624  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
625 }
626 
627 template <>
628 void speedtest<double, 1>(size_t count)
629 {
630  using DataType_t = double;
631  static constexpr unsigned short kNDim = 1;
632 
634 
635  std::vector<double> input; // (count);
636  input.resize(count);
637 
638  double minVal = -5.0;
639  double maxVal = +5.0;
640  GenerateInput(input, minVal, maxVal, 0);
641 
642  // Make sure we have some overflow.
643  minVal *= 0.9;
644  maxVal *= 0.9;
645 
646  cout << '\n';
647 
648  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
649  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
650  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
651  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
652  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
653  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
654 
655  cout << '\n';
656 
657  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
658  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
659  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
660  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
661  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
662  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
663 
664  cout << '\n';
665 
666  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
667  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
668  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
669  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
670  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
671  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
672 
673  cout << '\n';
674 
675  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
676  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
677  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
678  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
679  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
680  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
681 }
682 
683 template <>
684 void speedtest<float, 1>(size_t count)
685 {
686  using DataType_t = float;
687  static constexpr unsigned short kNDim = 1;
688 
690 
691  std::vector<double> input; // (count);
692  input.resize(count);
693 
694  double minVal = -5.0;
695  double maxVal = +5.0;
696  GenerateInput(input, minVal, maxVal, 0);
697 
698  // Make sure we have some overflow.
699  minVal *= 0.9;
700  maxVal *= 0.9;
701 
702  cout << '\n';
703 
704  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
705  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
706  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
707  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
708  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
709  R7::Dim<DataType_t, kNDim>::EE::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
710 
711  cout << '\n';
712 
713  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
714  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
715  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
716  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
717  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
718  R7::Dim<DataType_t, kNDim>::II::Execute<R7::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
719 
720  cout << '\n';
721 
722  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
723  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
724  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
725  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
726  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
727  R6::Dim<DataType_t, kNDim>::EE::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
728 
729  cout << '\n';
730 
731  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
732  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillBuffered>(input, minVal, maxVal);
733  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
734  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fillN>(input, minVal, maxVal);
735  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
736  R6::Dim<DataType_t, kNDim>::II::Execute<R6::Dim<DataType_t, kNDim>::fill>(input, minVal, maxVal);
737 }
738 
739 void histspeedtest(size_t iter = 1e6, int what = 255)
740 {
741  if (what & 1)
742  speedtest<double, 2>(iter);
743  if (what & 2)
744  speedtest<float, 2>(iter);
745  if (what & 4)
746  speedtest<double, 1>(iter);
747  if (what & 8)
748  speedtest<float, 1>(iter);
749 }
750 
751 int main(int argc, char **argv)
752 {
753 
754  size_t iter = 1e7;
755  int what = 1 | 2 | 4 | 8;
756  if (argc > 1)
757  iter = atof(argv[1]);
758  if (argc > 2)
759  what = atoi(argv[2]);
760 
761  histspeedtest(iter, what);
762 }
c
#define c(i)
Definition: RSha256.hxx:119
gType
static int gType
Definition: proofexecv.cxx:43
RHist.hxx
fit1_py.fill
fill
Definition: fit1_py.py:6
speedtest< double, 1 >
void speedtest< double, 1 >(size_t count)
Definition: histspeedtest.cxx:628
GetHist< 1, float >
const char * GetHist< 1, float >()
Definition: histspeedtest.cxx:150
ROOT::Experimental::RAxisConfig
Definition: RAxisConfig.hxx:47
GetHist
const char * GetHist()
GenerateInput
void GenerateInput(std::vector< T > &numbers, double minVal, double maxVal, UInt_t seed)
Definition: histspeedtest.cxx:108
R6::gVersion
const char * gVersion
Definition: histspeedtest.cxx:321
TH2F
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:251
r
ROOT::R::TRInterface & r
Definition: Object.C:4
string_view
basic_string_view< char > string_view
Definition: libcpp_string_view.h:785
TH1D
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:615
x
Double_t x[n]
Definition: legend1.C:17
histspeedtest
void histspeedtest(size_t iter=1e6, int what=255)
Definition: histspeedtest.cxx:739
long
long
Definition: Converters.cxx:858
GetHist< 2, float >
const char * GetHist< 2, float >()
Definition: histspeedtest.cxx:139
MakeTitle
std::string MakeTitle(std::string_view version, std::string_view histname, std::string_view title, std::string_view axis)
Definition: histspeedtest.cxx:123
R6
Definition: histspeedtest.cxx:320
TRandom3
Definition: TRandom3.h:27
gRepeat
constexpr unsigned short gRepeat
Definition: histspeedtest.cxx:22
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
gStride
constexpr UInt_t gStride
Definition: histspeedtest.cxx:78
TH1::AddDirectory
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition: TH1.cxx:1225
TH2D
2-D histogram with a double per channel (see TH1 documentation)}
Definition: TH2.h:292
main
int main(int argc, char **argv)
Definition: histspeedtest.cxx:751
TH1::GetDefaultBufferSize
static Int_t GetDefaultBufferSize()
Static function return the default buffer size for automatic histograms the parameter fgBufferSize ma...
Definition: TH1.cxx:4284
TRandom3.h
what
static const char * what
Definition: stlLoader.cc:6
GetHist< 2, double >
const char * GetHist< 2, double >()
Definition: histspeedtest.cxx:134
double
double
Definition: Converters.cxx:921
speedtest< float, 2 >
void speedtest< float, 2 >(size_t count)
Definition: histspeedtest.cxx:572
y
Double_t y[n]
Definition: legend1.C:17
ROOT::Experimental::Hist::RCoordArray
Definition: RHistUtils.hxx:44
TH2.h
speedtest< double, 2 >
void speedtest< double, 2 >(size_t count)
Definition: histspeedtest.cxx:512
unsigned int
TH3.h
ROOT::Experimental::RHistBufferedFill
Definition: RHistBufferedFill.hxx:94
speedtest
void speedtest(size_t count=(size_t)(1e6))
TH1F
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:572
speedtest< float, 1 >
void speedtest< float, 1 >(size_t count)
Definition: histspeedtest.cxx:684
ROOT::Experimental::Internal::swap
void swap(RDirectoryEntry &e1, RDirectoryEntry &e2) noexcept
Definition: RDirectoryEntry.hxx:112
GetHist< 1, double >
const char * GetHist< 1, double >()
Definition: histspeedtest.cxx:145
ROOT::Math::Chebyshev::T
double T(double x)
Definition: ChebyshevPol.h:52
ROOT::Experimental::RHist
Definition: RHist.hxx:44
type
int type
Definition: TGX11.cxx:121
TH1.h
ROOT
VSD Structures.
Definition: StringConv.hxx:21
RHistBufferedFill.hxx
RooFit::Timer
RooCmdArg Timer(Bool_t flag=kTRUE)
Definition: RooGlobalFunc.cxx:188
R7
Definition: histspeedtest.cxx:155