[RF] Speedup histfactory ParamHistFunc#7838
Conversation
|
Starting build on |
|
Build failed on ROOT-fedora31/noimt. Failing tests: |
|
Build failed on ROOT-ubuntu16/nortcxxmod. Failing tests: |
|
Nice find. This might conflict with my HistFactory branch, but go ahead and I can rebase once it's in. |
| if( numVars == 1 ) { | ||
| RooRealVar* varX = (RooRealVar*) _dataVars.at(0); | ||
| numBinsX = varX->numBins(); | ||
| numBinsY = 1; | ||
| numBinsZ = 1; | ||
| numBinsX = static_cast<RooRealVar const&>(_dataVars[0]).numBins(); | ||
| } else if( numVars == 2 ) { | ||
| RooRealVar* varX = (RooRealVar*) _dataVars.at(0); | ||
| RooRealVar* varY = (RooRealVar*) _dataVars.at(1); | ||
| numBinsX = varX->numBins(); | ||
| numBinsY = varY->numBins(); | ||
| numBinsZ = 1; | ||
| numBinsX = static_cast<RooRealVar const&>(_dataVars[0]).numBins(); | ||
| numBinsY = static_cast<RooRealVar const&>(_dataVars[1]).numBins(); | ||
| } else if( numVars == 3 ) { | ||
| RooRealVar* varX = (RooRealVar*) _dataVars.at(0); | ||
| RooRealVar* varY = (RooRealVar*) _dataVars.at(1); | ||
| RooRealVar* varZ = (RooRealVar*) _dataVars.at(2); | ||
| numBinsX = varX->numBins(); | ||
| numBinsY = varY->numBins(); | ||
| numBinsZ = varZ->numBins(); | ||
| numBinsX = static_cast<RooRealVar const&>(_dataVars[0]).numBins(); | ||
| numBinsY = static_cast<RooRealVar const&>(_dataVars[1]).numBins(); | ||
| numBinsZ = static_cast<RooRealVar const&>(_dataVars[2]).numBins(); |
There was a problem hiding this comment.
Why not replace those three branches with code repetition by:
if (numVars >= 1) numBinsX = static_cast<RooRealVar const&>(_dataVars[0]).numBins();
if (numVars >= 2) numBinsY = static_cast<RooRealVar const&>(_dataVars[1]).numBins();
...And I would assume that numVars > 0. You could check.
There was a problem hiding this comment.
Or if you want to go more RAII:
const int numBinsX = numVars >= 1 ? static_cast<RooRealVar const&>(_dataVars[0]).numBins() : 1;
...| coutE(InputArguments) << "ParamHistFunc::(" << GetName() << ") ERROR: component " | ||
| << comp->GetName() << " in variables list is not of type RooRealVar" | ||
| << std::endl; | ||
| RooErrorHandler::softAbort() ; |
There was a problem hiding this comment.
Please remove that. The idea was that you would be dropped back to the terminal, but it doesn't work in interpreter mode.
Better throw an exception, because that will actually drop you back to the terminal.
When used from a compiled program, it just ends the program with an uncaught exception.
There was a problem hiding this comment.
Context: This used to work in ROOT 5, but those times are gone.
75e44bf to
3bba3f3
Compare
|
Starting build on |
| return -1; | ||
| auto errorMsg = std::string("ParamHistFunc::GetNumBins") + vars.GetName() + ") ERROR: component " | ||
| + comp->GetName() + " in vars list is not of type RooRealVar"; | ||
| std::cout << errorMsg << std::endl; |
There was a problem hiding this comment.
It unfortunately doesn't work in a static function. Do you have an alternative suggestion? There is oocoutE, but I'm not sure if it makes sense because you have to give it a caller.
There was a problem hiding this comment.
A static_cast<TObject*>(nullptr) works fine. The caller is only necessary to print its name. If it's nullptr, that name printing is skipped.
3bba3f3 to
460cc0b
Compare
|
Starting build on |
| RooFIter varIter = vars.fwdIterator() ; | ||
| RooAbsArg* comp ; | ||
| while((comp = (RooAbsArg*) varIter.next())) { |
There was a problem hiding this comment.
If you are at it anyway:
for (auto arg : vars) {
...Those loops are ~20% faster (which doesn't make a difference here), but well. 🙂
The ParamHistFunc in the histfactory has a persistent std::map<int,int> data member. It can be replaced with a std::vector<int> where the previous key is the index in the vector. This is much faster. Schema evolution is not a problem here. With this commit, the data member is made non-persistent because it can be computed from other persistent data members.
460cc0b to
418288c
Compare
Benchmarking showed that calculating the bin indices in ParamHistFunc on the fly is faster than caching them in a std::vector.
|
Starting build on |
The ParamHistFunc in the histfactory has a persistent
std::map<int,int>data member. It can be replaced with a
std::vector<int>where theprevious key is the index in the vector. This is much faster.
As the igprof reports below show, it is even faster to calculate the bin indices on the fly, which is proposed in this PR.
Schema evolution is not a problem here. With this commit, the data
member is made non-persistent because it can be computed from other
persistent data members.
This PR was benchmarked with an example from the ROOT forum:
std::map)std::vector)The difference is about a 50 % speedup of
ParamHistFunc::evaluate()and a 10 % speedup of the full example.