{
"cells": [
{
"cell_type": "markdown",
"id": "47c74373",
"metadata": {},
"source": [
"# tree202_benchmarks\n",
"Benchmark comparing row-wise and column-wise storage performance\n",
"\n",
"The test consists in writing/reading to/from keys or trees\n",
"To execute the benchmark:\n",
"```\n",
"root -b -q tree202_benchmarks.C or root -b -q tree202_benchmarks.C++\n",
"```\n",
"for example for N=10000, the following output is produced\n",
"on an 2.7 GHz Intel Core i7 (year 2011).\n",
"The names featuring a \"t\" are relative to trees, the faster, the better.\n",
"```\n",
"billw0 : RT= 0.803 s, Cpu= 0.800 s, File size= 45608143 bytes, CX= 1\n",
"billr0 : RT= 0.388 s, Cpu= 0.390 s\n",
"billtw0 : RT= 0.336 s, Cpu= 0.310 s, File size= 45266881 bytes, CX= 1.00034\n",
"billtr0 : RT= 0.229 s, Cpu= 0.230 s\n",
"billw1 : RT= 1.671 s, Cpu= 1.670 s, File size= 16760526 bytes, CX= 2.72078\n",
"billr1 : RT= 0.667 s, Cpu= 0.680 s\n",
"billtw1 : RT= 0.775 s, Cpu= 0.770 s, File size= 9540884 bytes, CX= 4.74501\n",
"billtr1 : RT= 0.352 s, Cpu= 0.350 s\n",
"billtot : RT= 5.384 s, Cpu= 5.290 s\n",
"******************************************************************\n",
"* ROOTMARKS =1763.9 * Root6.05/03 20150914/948\n",
"******************************************************************\n",
"```\n",
"\n",
"\n",
"**Author:** Rene Brun \n",
"This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Tuesday, May 19, 2026 at 08:19 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "15b8f9f4",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:19:50.313317Z",
"iopub.status.busy": "2026-05-19T20:19:50.313178Z",
"iopub.status.idle": "2026-05-19T20:19:50.325798Z",
"shell.execute_reply": "2026-05-19T20:19:50.325217Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \"TFile.h\"\n",
"#include \"TSystem.h\"\n",
"#include \"TH1.h\"\n",
"#include \"TRandom.h\"\n",
"#include \"TStopwatch.h\"\n",
"#include \"TKey.h\"\n",
"#include \"TTree.h\"\n",
"#include \"TROOT.h\"\n",
"\n",
"const Int_t N = 10000; //number of events to be processed\n",
"TStopwatch timer;"
]
},
{
"cell_type": "markdown",
"id": "a3af7df2",
"metadata": {},
"source": [
" Definition of a helper function: "
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "9f9976e2",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:19:50.327098Z",
"iopub.status.busy": "2026-05-19T20:19:50.326975Z",
"iopub.status.idle": "2026-05-19T20:19:50.336453Z",
"shell.execute_reply": "2026-05-19T20:19:50.335913Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"void billw(const char *billname, Int_t compress)\n",
"{\n",
" //write N histograms as keys\n",
" timer.Start();\n",
" TFile f(billname, \"recreate\", \"bill benchmark with keys\", compress);\n",
" TH1F h(\"h\", \"h\", 1000, -3, 3);\n",
" h.FillRandom(\"gaus\", 50000);\n",
"\n",
" for (Int_t i = 0; i < N; i++) {\n",
" char name[20];\n",
" sprintf(name, \"h%d\", i);\n",
" h.SetName(name);\n",
" h.Fill( 2 * gRandom->Rndm());\n",
" h.Write();\n",
" }\n",
" timer.Stop();\n",
" printf(\"billw%d : RT=%7.3f s, Cpu=%7.3f s, File size= %9d bytes, CX= %g\\n\",\n",
" compress, timer.RealTime(), timer.CpuTime(), (Int_t)f.GetBytesWritten(),\n",
" f.GetCompressionFactor());\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "1a5fa37b",
"metadata": {},
"source": [
" Definition of a helper function: "
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "a9caa7aa",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:19:50.337744Z",
"iopub.status.busy": "2026-05-19T20:19:50.337620Z",
"iopub.status.idle": "2026-05-19T20:19:50.345134Z",
"shell.execute_reply": "2026-05-19T20:19:50.344644Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"void billr(const char *billname, Int_t compress)\n",
"{\n",
" TDirectory::TContext ctx{nullptr}; // Don't register histograms to the current directory\n",
"\n",
" //read N histograms from keys\n",
" timer.Start();\n",
" TFile f(billname);\n",
" TIter next(f.GetListOfKeys());\n",
" TH1F *h;\n",
"\n",
" TKey *key;\n",
" Int_t i = 0;\n",
" auto hmean = new TH1F(\"hmean\", \"hist mean from keys\", 100, 0, 1);\n",
"\n",
" while ((key = (TKey*)next())) {\n",
" h = (TH1F*)key->ReadObj();\n",
" hmean->Fill(h->GetMean());\n",
" delete h;\n",
" i++;\n",
" }\n",
" timer.Stop();\n",
" printf(\"billr%d : RT=%7.3f s, Cpu=%7.3f s\\n\", compress, timer.RealTime(), timer.CpuTime());\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "9dedfc17",
"metadata": {},
"source": [
" Definition of a helper function: "
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "ec7bdc91",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:19:50.346545Z",
"iopub.status.busy": "2026-05-19T20:19:50.346422Z",
"iopub.status.idle": "2026-05-19T20:19:50.356475Z",
"shell.execute_reply": "2026-05-19T20:19:50.355980Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"void billtw(const char *billtname, Int_t compress)\n",
"{\n",
" //write N histograms to a Tree\n",
" timer.Start();\n",
" TFile f(billtname,\"recreate\", \"bill benchmark with trees\", compress);\n",
" auto h = new TH1F(\"h\", \"h\", 1000, -3, 3);\n",
" h->FillRandom(\"gaus\", 50000);\n",
" auto T = new TTree(\"T\", \"test bill\");\n",
" T->Branch(\"event\", \"TH1F\", &h, 64000, 0);\n",
" for (Int_t i = 0; i < N; i++) {\n",
" char name[20];\n",
" sprintf(name, \"h%d\", i);\n",
" h->SetName(name);\n",
" h->Fill(2 * gRandom->Rndm());\n",
" T->Fill();\n",
" }\n",
" T->Write();\n",
" delete T;\n",
" timer.Stop();\n",
" printf(\"billtw%d : RT=%7.3f s, Cpu=%7.3f s, File size= %9d bytes, CX= %g\\n\",\n",
" compress, timer.RealTime(), timer.CpuTime(), (Int_t)f.GetBytesWritten(),\n",
" f.GetCompressionFactor());\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "b5db09ed",
"metadata": {},
"source": [
" Definition of a helper function: "
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "53e82bdd",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:19:50.357755Z",
"iopub.status.busy": "2026-05-19T20:19:50.357631Z",
"iopub.status.idle": "2026-05-19T20:19:50.363130Z",
"shell.execute_reply": "2026-05-19T20:19:50.362645Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"void billtr(const char *billtname, Int_t compress)\n",
"{\n",
" //read N histograms from a tree\n",
" timer.Start();\n",
" TFile f(billtname);\n",
" TH1F *h = nullptr;\n",
" auto T = f.Get(\"T\");\n",
" T->SetBranchAddress(\"event\", &h);\n",
" auto hmeant = new TH1F(\"hmeant\", \"hist mean from tree\", 100, 0, 1);\n",
" Long64_t nentries = T->GetEntries();\n",
" for (Long64_t i = 0; i < nentries; i++) {\n",
" T->GetEntry(i);\n",
" hmeant->Fill(h->GetMean());\n",
" }\n",
" timer.Stop();\n",
" printf(\"billtr%d : RT=%7.3f s, Cpu=%7.3f s\\n\", compress, timer.RealTime(), timer.CpuTime());\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "a2c6c658",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:19:50.364381Z",
"iopub.status.busy": "2026-05-19T20:19:50.364259Z",
"iopub.status.idle": "2026-05-19T20:19:52.001774Z",
"shell.execute_reply": "2026-05-19T20:19:52.001337Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"billw0 : RT= 0.189 s, Cpu= 0.190 s, File size= 45768009 bytes, CX= 1\n",
"billr0 : RT= 0.070 s, Cpu= 0.070 s\n",
"billtw0 : RT= 0.078 s, Cpu= 0.080 s, File size= 45442819 bytes, CX= 1\n",
"billtr0 : RT= 0.036 s, Cpu= 0.030 s\n",
"billw1 : RT= 0.485 s, Cpu= 0.500 s, File size= 16740543 bytes, CX= 2.73358\n",
"billr1 : RT= 0.151 s, Cpu= 0.150 s\n",
"billtw1 : RT= 0.102 s, Cpu= 0.110 s, File size= 2713423 bytes, CX= 16.7431\n",
"billtr1 : RT= 0.036 s, Cpu= 0.030 s\n",
"billtot : RT= 1.223 s, Cpu= 1.200 s\n"
]
}
],
"source": [
"TString dir = gSystem->GetDirName(gSystem->UnixPathName(__FILE__));\n",
"TString bill = dir + \"/bill.root\";\n",
"TString billt = dir + \"/billt.root\";\n",
"\n",
"TStopwatch totaltimer;\n",
"totaltimer.Start();\n",
"for (Int_t compress = 0; compress < 2; compress++) {\n",
" billw(bill, compress);\n",
" billr(bill, compress);\n",
" billtw(billt, compress);\n",
" billtr(billt, compress);\n",
"}\n",
"gSystem->Unlink(bill);\n",
"gSystem->Unlink(billt);\n",
"totaltimer.Stop();\n",
"Double_t realtime = totaltimer.RealTime();\n",
"Double_t cputime = totaltimer.CpuTime();\n",
"printf(\"billtot : RT=%7.3f s, Cpu=%7.3f s\\n\", realtime, cputime);"
]
},
{
"cell_type": "markdown",
"id": "6c7517b7",
"metadata": {},
"source": [
"reference is a P IV 2.4 GHz"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "4f548342",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:19:52.003174Z",
"iopub.status.busy": "2026-05-19T20:19:52.003065Z",
"iopub.status.idle": "2026-05-19T20:19:52.207110Z",
"shell.execute_reply": "2026-05-19T20:19:52.206665Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"******************************************************************\n",
"* ROOTMARKS =7771.1 * Root6.41.01 20260423/0\n",
"******************************************************************\n"
]
}
],
"source": [
"Float_t rootmarks = 600 * (16.98 + 14.40) / (realtime + cputime);\n",
"printf(\"******************************************************************\\n\");\n",
"printf(\"* ROOTMARKS =%6.1f * Root%-8s %d/%d\\n\", rootmarks,\n",
" gROOT->GetVersion(), gROOT->GetVersionDate(), gROOT->GetVersionTime());\n",
"printf(\"******************************************************************\\n\");"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "ROOT C++",
"language": "c++",
"name": "root"
},
"language_info": {
"codemirror_mode": "text/x-c++src",
"file_extension": ".C",
"mimetype": " text/x-c++src",
"name": "c++"
}
},
"nbformat": 4,
"nbformat_minor": 5
}