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