52#define INT_MAX std::numeric_limits<int>::max() 
   57   enum EHist { kHist, kSparse, kNumHist };
 
   58   enum ETime { kReal, kCPU, kNumTime };
 
   60      fValue(0), fDim(dim), fBins(bins), fNum(num),
 
   61      fSparse(0), fHist(0), fHn(0) {}
 
   64   Double_t GetTime(EHist hist, ETime time)
 const {
 
   65      if (time == kReal) 
return fTime[hist][0];
 
   66      return fTime[hist][1]; }
 
   67   static void SetDebug(
Int_t lvl) { fgDebug = lvl; }
 
   68   THnSparse* GetSparse()
 const { 
return fSparse; }
 
   71   void Fill(EHist hist);
 
   73   void SetupHist(EHist hist);
 
   89Int_t TTimeHists::fgDebug = 0;
 
   91TTimeHists::~TTimeHists()
 
  105   for (
int h = 0; 
h < 2; ++
h) {
 
  111         SetupHist((EHist) 
h);
 
  116            check[
h] = Check((EHist) 
h);
 
  119         } 
while ((!
h && 
w.RealTime() < 0.1)
 
  120            || (
h && rep[0] > 0 && rep[1] < rep[0]));
 
  122         fTime[
h][0] = (1.* fNum * rep[
h]) / 
w.RealTime() / 1E6;
 
  123         fTime[
h][1] = (1.* fNum * rep[
h]) / 
w.CpuTime() / 1E6;
 
  125         if (
h == 1 && (fTime[
h][0] > 1E20 || fTime[
h][1] > 1E20)) {
 
  133            } 
while (
w.RealTime() < 0.1);
 
  135            fTime[
h][0] = (1.* fNum * rep[
h]) / 
w.RealTime() / 1E6;
 
  136            fTime[
h][1] = (1.* fNum * rep[
h]) / 
w.CpuTime() / 1E6;
 
  139         if (fTime[
h][0] > 1E20) fTime[
h][0] = 1E20;
 
  140         if (fTime[
h][1] > 1E20) fTime[
h][1] = 1E20;
 
  142      catch (std::exception&) {
 
  143         fTime[
h][0] = fTime[
h][1] = -1.;
 
  148   if (check[0] != check[1])
 
  150         printf(
"ERROR: mismatch of histogram (%g) and sparse histogram (%g) for dim=%d, bins=%d!\n",
 
  151                check[0], check[1], fDim, fBins);
 
  155   return (check[0] == check[1]);
 
  158void TTimeHists::NextValues()
 
  164void TTimeHists::SetupValues()
 
  167   if (!fValue) fValue = 
new Double_t[fDim];
 
  171void TTimeHists::Fill(EHist hist)
 
  176         printf(
"%ld: fill %s", 
n, hist == kHist? (fDim < 4 ? 
"hist" : 
"arr") : 
"sparse");
 
  178            printf(
"[%g]", fValue[
d]);
 
  183         case 1: fHist->Fill(fValue[0]); 
break;
 
  184         case 2: ((
TH2F*)fHist)->Fill(fValue[0], fValue[1]); 
break;
 
  185         case 3: ((
TH3F*)fHist)->Fill(fValue[0], fValue[1], fValue[2]); 
break;
 
  186         default: fHn->Fill(fValue); 
break;
 
  189         fSparse->Fill(fValue);
 
  194void TTimeHists::SetupHist(EHist hist)
 
  198      case 1: fHist = 
new TH1F(
"h1", 
"h1", fBins, -1., 1.); 
break;
 
  199      case 2: fHist = 
new TH2F(
"h2", 
"h2", fBins, -1., 1., fBins, -1., 1.); 
break;
 
  200      case 3: fHist = 
new TH3F(
"h3", 
"h3", fBins, -1., 1., fBins, -1., 1., fBins, -1., 1.); 
break;
 
  210                  throw std::bad_alloc();
 
  215               throw std::bad_alloc();
 
  240Double_t TTimeHists::Check(EHist hist)
 
  245   memset(
x, 0, 
sizeof(
Int_t) * fDim);
 
  252      while (
x[0] <= fBins + 1) {
 
  256            if (fDim == 2) histidx = fHist->GetBin(
x[0], 
x[1]);
 
  257            else if (fDim == 3) histidx = fHist->GetBin(
x[0], 
x[1], 
x[2]);
 
  258            v = fHist->GetBinContent(histidx);
 
  260         else v = fHn->GetBinContent(
x);
 
  267         if (fgDebug > 2 || (fgDebug > 1 && 
v)) {
 
  268            printf(
"%s%d", fDim < 4 ? 
"hist" : 
"arr", fDim);
 
  270               printf(
"[%d]", 
x[
d]);
 
  271            printf(
" = %g\n", 
v);
 
  277         for (
Int_t d = fDim - 1; 
d > 0; --
d) {
 
  278            if (
x[
d] > fBins + 1) {
 
  286      for (
Long64_t i = 0; i < fSparse->GetNbins(); ++i) {
 
  294            printf(
"sparse%d", fDim);
 
  296               printf(
"[%d]", 
x[
d]);
 
  297            printf(
" = %g\n", 
v);
 
  303      printf(
"check %s%d = %g\n", hist == kHist ? (fDim < 4 ? 
"hist" : 
"arr") : 
"sparse", fDim, check);
 
  311#if defined (__CLING__) 
  312   printf(
"Please run this script in compiled mode by running \".x sparsehist.C+\"\n");
 
  316   TH2F* htime[TTimeHists::kNumHist][TTimeHists::kNumTime];
 
  317   for (
int h = 0; 
h < TTimeHists::kNumHist; ++
h)
 
  318      for (
int t = 0; t < TTimeHists::kNumTime; ++t) {
 
  320         if (
h == 0) 
name += 
"arr";
 
  322         if (t == 0) 
name += 
"_r";
 
  325         title.
Form(
"Throughput (fill,get) %s (%s, 1M entries/sec);dim;bins;1M entries/sec", 
h == 0 ? 
"TH1/2/3/nF" : 
"THnSparseF", t == 0 ? 
"real" : 
"CPU");
 
  326         htime[
h][t] = 
new TH2F(
name, title, 6, 0.5, 6.5, 10, 5, 105);
 
  329   TH2F* hsparse_mem = 
new TH2F(
"hsparse_mem", 
"Fractional memory usage;dim;bins;fraction of memory used", 6, 0.5, 6.5, 10, 5, 105);
 
  330   TH2F* hsparse_bins = 
new TH2F(
"hsparse_bins", 
"Fractional number of used bins;dim;bins;fraction of filled bins", 6, 0.5, 6.5, 10, 5, 105);
 
  334   for (
Int_t dim = 1; dim < 7; ++dim) {
 
  335      printf(
"Processing dimension %d", dim);
 
  336      for (
Int_t bins = 10; bins <= 100; bins += 10) {
 
  337         TTimeHists timer(dim, bins,  1000);
 
  339         for (
int h = 0; 
h < TTimeHists::kNumHist; ++
h) {
 
  340            for (
int t = 0; t < TTimeHists::kNumTime; ++t) {
 
  341               Double_t time = timer.GetTime((TTimeHists::EHist)
h, (TTimeHists::ETime)t);
 
  343                  htime[
h][t]->
Fill(dim, bins, time);
 
  346         hsparse_mem->
Fill(dim, bins, timer.GetSparse()->GetSparseFractionMem());
 
  347         hsparse_bins->
Fill(dim, bins, timer.GetSparse()->GetSparseFractionBins());
 
  349         if (max < timer.GetTime(TTimeHists::kSparse, TTimeHists::kReal))
 
  350            max = timer.GetTime(TTimeHists::kSparse, TTimeHists::kReal);
 
  361   TH2F* htime_ratio[TTimeHists::kNumTime];
 
  362   for (
int t = 0; t < TTimeHists::kNumTime; ++t) {
 
  363      const char* 
name = t ? 
"htime_ratio" : 
"htime_ratio_r";
 
  364      htime_ratio[t] = (
TH2F*) htime[TTimeHists::kSparse][t]->Clone(
name);
 
  366      title.
Form(
"Relative speed improvement (%s, 1M entries/sec): sparse/hist;dim;bins;#Delta 1M entries/sec", t == 0 ? 
"real" : 
"CPU");
 
  368      htime_ratio[t]->
Divide(htime[TTimeHists::kHist][t]);
 
  373   TFile* 
f = 
new TFile(
"sparsehist.root",
"RECREATE");
 
  381   const char* opt = 
"TEXT COL";
 
  383   for (
int t = 0; t < TTimeHists::kNumTime; ++t) {
 
  384      for (
int h = 0; 
h < TTimeHists::kNumHist; ++
h) {
 
  387         canv->
cd(1 + 
h + 3 * t);
 
  388         htime[
h][t]->
Draw(opt);
 
  392      htime_ratio[t]->
Draw(opt); 
gPad->SetLogz();
 
  393      htime_ratio[t]->
Write();
 
  396   canv->
cd(7); hsparse_mem->
Draw(opt);
 
  397   canv->
cd(8); hsparse_bins->
Draw(opt);
 
  398   hsparse_mem->
Write();
 
  399   hsparse_bins->
Write();
 
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
 
THnSparseT< TArrayF > THnSparseF
 
R__EXTERN TRandom * gRandom
 
R__EXTERN TStyle * gStyle
 
R__EXTERN TSystem * gSystem
 
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
 
TVirtualPad * cd(Int_t subpadnumber=0) override
Set current canvas & pad.
 
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
 
1-D histogram with a float per channel (see TH1 documentation)}
 
TH1 is the base class of all histogram classes in ROOT.
 
void SetTitle(const char *title) override
Change (i.e.
 
virtual void SetMaximum(Double_t maximum=-1111)
 
void Draw(Option_t *option="") override
Draw this histogram with options.
 
virtual void SetMinimum(Double_t minimum=-1111)
 
virtual Bool_t Divide(TF1 *f1, Double_t c1=1)
Performs the operation: this = this/(c1*f1) if errors are defined (see TH1::Sumw2),...
 
2-D histogram with a float per channel (see TH1 documentation)}
 
Int_t Fill(Double_t) override
Invalid Fill method.
 
3-D histogram with a float per channel (see TH1 documentation)}
 
Efficient multidimensional histogram.
 
Multidimensional histogram.
 
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
 
void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0) override
Automatic pad generation by division.
 
virtual Double_t Gaus(Double_t mean=0, Double_t sigma=1)
Samples a random number from the standard Normal (Gaussian) Distribution with the given mean and sigm...
 
virtual void SetSeed(ULong_t seed=0)
Set the random generator seed.
 
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
 
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
 
void SetOptStat(Int_t stat=1)
The type of information printed in the histogram statistics box can be selected via the parameter mod...
 
void SetPaintTextFormat(const char *format="g")
 
void SetPalette(Int_t ncolors=kBird, Int_t *colors=nullptr, Float_t alpha=1.)
See TColor::SetPalette.
 
virtual int GetMemInfo(MemInfo_t *info) const
Returns ram and swap memory usage info into the MemInfo_t structure.