{ "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 }