void TimerData::print() { static ctime_t tmargin = CTime::getTicksPerSec() / 100000; std::ostream& out = std::cout; out << "==== " << id << " ====\n\n"; if (!records.empty()) { out << "Trace of last iteration :\n"; ctime_t t0 = records[0].time; ctime_t last_t = 0; int level = 0; for (unsigned int ri = 1; ri < records.size(); ++ri) { const Record& r = records[ri]; out << " * "; if (ri > 0 && ri < records.size()-1 && r.time <= last_t + tmargin) { printNoVal(out); out << " "; } else { printTime(out, r.time - t0); out << " ms"; last_t = r.time; } out << " "; if (r.type == Record::REND || r.type == Record::RSTEP_END) --level; for (int l=0; l<level; ++l) out << " "; switch(r.type) { case Record::RNONE: out << "NONE"; break; case Record::RSTEP_BEGIN: out << "> begin " << AdvancedTimer::IdStep(r.id); if (r.obj) out << " on " << AdvancedTimer::IdObj(r.obj); break; case Record::RSTEP_END: out << "< end " << AdvancedTimer::IdStep(r.id); if (r.obj) out << " on " << AdvancedTimer::IdObj(r.obj); break; case Record::RSTEP: out << "- step " << AdvancedTimer::IdStep(r.id); if (r.obj) out << " on " << AdvancedTimer::IdObj(r.obj); break; case Record::RVAL_SET: out << ": var " << AdvancedTimer::IdVal(r.id); out << " = " << r.val; break; case Record::RVAL_ADD: out << ": var " << AdvancedTimer::IdVal(r.id); out << " += " << r.val; break; case Record::REND: out << "END"; break; default: out << "UNKNOWN RECORD TYPE" << (int)r.type; } out << std::endl; if (r.type == Record::RBEGIN || r.type == Record::RSTEP_BEGIN) ++level; } } if (!steps.empty()) { out << "\nSteps Duration Statistics (in ms) :\n"; out << " LEVEL\t START\t NUM\t MIN\t MAX\t MEAN\t DEV\t TOTAL\tPERCENT\tID\n"; ctime_t ttotal = stepData[AdvancedTimer::IdStep()].ttotal; for (unsigned int s=0; s<steps.size(); ++s) { StepData& data = stepData[steps[s]]; printVal(out, data.level); out << '\t'; printTime(out, data.tstart, data.numIt); out << '\t'; printVal(out, data.num, (s == 0) ? 1 : nbIter); out << '\t'; printTime(out, data.tmin); out << '\t'; printTime(out, data.tmax); out << '\t'; double mean = (double)data.ttotal / data.num; printTime(out, (ctime_t)mean); out << '\t'; printTime(out, (ctime_t)(sqrt((double)data.ttotal2/data.num - mean*mean))); out << '\t'; printTime(out, data.ttotal, (s == 0) ? 1 : nbIter); out << '\t'; printVal(out, 100.0*data.ttotal / (double) ttotal); out << '\t'; if (s == 0) out << "TOTAL"; else { for(int ii=0; ii<data.level; ii++) out<<"."; // indentation to show the hierarchy level out << steps[s]; } out << std::endl; } } if (!vals.empty()) { out << "\nValues Statistics :\n"; out << " NUM\t MIN\t MAX\t MEAN\t DEV\t TOTAL\tID\n"; for (unsigned int s=0; s<vals.size(); ++s) { ValData& data = valData[vals[s]]; printVal(out, data.num, nbIter); out << '\t'; printVal(out, data.vmin); out << '\t'; printVal(out, data.vmax); out << '\t'; double mean = data.vtotal / data.num; printVal(out, mean); out << '\t'; printVal(out, sqrt(data.vtotal2/data.num - mean*mean) ); out << '\t'; printVal(out, data.vtotal, nbIter); out << '\t'; out << vals[s]; out << std::endl; } } out << "\n iteration : " << getCurRecords()->size(); out << "\n==== END ====\n"; out << std::endl; }
json TimerData::getLightJson(std::string stepNumber) { json jsonOutput; std::vector<std::string> deepthTree; std::string jsonObjectName = stepNumber; std::string father; int componantLevel = 0; int subComponantLevel = 0; std::stringstream ComposantId; if (!steps.empty()) { // Clean the streamString ComposantId.str(""); componantLevel = 0; subComponantLevel = 0; // Create the JSON container jsonOutput[jsonObjectName]; for (unsigned int s=0; s<steps.size(); s++) { // Clean the streamString ComposantId.str(""); StepData& data = stepData[steps[s]]; if (s == 0) { ComposantId << "TOTAL"; deepthTree.push_back(ComposantId.str()); subComponantLevel = 0; jsonOutput[jsonObjectName][ComposantId.str()]["Father"] = "None"; jsonOutput[jsonObjectName][ComposantId.str()]["Values"] = createJSONArray(s, jsonOutput[jsonObjectName][ComposantId.str()]["Values"], data); } else { for(int ii=0; ii<data.level; ii++) ++subComponantLevel; // indentation to show the hierarchy level // If the level increment if(componantLevel < subComponantLevel) { father = deepthTree.at(deepthTree.size()-1); ComposantId << steps[s]; deepthTree.push_back(ComposantId.str()); jsonOutput[jsonObjectName][ComposantId.str()]["Father"] = father; jsonOutput[jsonObjectName][ComposantId.str()]["Values"] = createJSONArray(s, jsonOutput[jsonObjectName][ComposantId.str()]["Values"], data);; } // If the level decrement else if(componantLevel > subComponantLevel) { deepthTree.pop_back(); father = deepthTree.at(deepthTree.size()-1); ComposantId << steps[s]; jsonOutput[jsonObjectName][ComposantId.str()]["Father"] = father; jsonOutput[jsonObjectName][ComposantId.str()]["Values"] = createJSONArray(s, jsonOutput[jsonObjectName][ComposantId.str()]["Values"], data); } // If the level stay the same else if (componantLevel == subComponantLevel) { ComposantId << steps[s]; jsonOutput[jsonObjectName][ComposantId.str()]["Father"] = father; jsonOutput[jsonObjectName][ComposantId.str()]["Values"] = createJSONArray(s, jsonOutput[jsonObjectName][ComposantId.str()]["Values"], data); } } componantLevel = subComponantLevel; subComponantLevel = 0; } } return jsonOutput; }
void TimerData::process() { if (records.empty()) return; ++nbIter; if (nbIter == 0) return; // do not keep stats on very first iteration ctime_t t0 = records[0].time; //ctime_t last_t = 0; int level = 0; for (unsigned int ri = 0; ri < records.size(); ++ri) { const Record& r = records[ri]; ctime_t t = r.time - t0; //last_t = r.time; if (r.type == Record::REND || r.type == Record::RSTEP_END) --level; switch (r.type) { case Record::RNONE: break; case Record::RBEGIN: case Record::RSTEP_BEGIN: case Record::RSTEP: { AdvancedTimer::IdStep id; if (r.type != Record::RBEGIN) id = AdvancedTimer::IdStep(r.id); if (stepData.find(id) == stepData.end()) steps.push_back(id); StepData& data = stepData[id]; data.level = level; if (data.lastIt != nbIter) { data.lastIt = nbIter; data.tstart += t; ++data.numIt; } data.lastTime = t; ++data.num; break; } case Record::REND: case Record::RSTEP_END: { AdvancedTimer::IdStep id; if (r.type != Record::REND) id = AdvancedTimer::IdStep(r.id); StepData& data = stepData[id]; if (data.lastIt == nbIter) { ctime_t dur = t - data.lastTime; data.ttotal += dur; data.ttotal2 += dur*dur; if (data.num == 1 || dur > data.tmax) data.tmax = dur; if (data.num == 1 || dur < data.tmin) data.tmin = dur; } break; } case Record::RVAL_SET: case Record::RVAL_ADD: { AdvancedTimer::IdVal id = AdvancedTimer::IdVal(r.id); if (valData.find(id) == valData.end()) vals.push_back(id); ValData& data = valData[id]; if (r.type == Record::RVAL_SET || (data.lastIt != nbIter)) { // update vmin and vmax if (data.num == 1 || data.vtotalIt < data.vmin) data.vmin = data.vtotalIt; if (data.num == 1 || data.vtotalIt > data.vmax) data.vmax = data.vtotalIt; } if (data.lastIt != nbIter) { data.lastIt = nbIter; data.vtotalIt = r.val; data.vtotal += r.val; data.vtotal2 += r.val*r.val; ++data.numIt; ++data.num; } else if (r.type == Record::RVAL_SET) { data.vtotalIt = r.val; data.vtotal += r.val; data.vtotal2 += r.val*r.val; ++data.num; } else { data.vtotalIt += r.val; data.vtotal += r.val; data.vtotal2 += r.val*r.val; } break; } } if (r.type == Record::RBEGIN || r.type == Record::RSTEP_BEGIN) ++level; } for (unsigned int vi=0; vi < vals.size(); ++vi) { AdvancedTimer::IdVal id = vals[vi]; ValData& data = valData[id]; if (data.num > 0) { // update vmin and vmax if (data.num == 1 || data.vtotalIt < data.vmin) data.vmin = data.vtotalIt; if (data.num == 1 || data.vtotalIt > data.vmax) data.vmax = data.vtotalIt; } } }
void TimerData::print(std::ostream& result) { //static ctime_t tmargin = CTime::getTicksPerSec() / 100000; std::ostream& out = result; out << "Timer: " << id << "\n"; if (!steps.empty()) { //out << "\nSteps Duration Statistics (in ms) :\n"; out << " LEVEL START NUM MIN MAX MEAN DEV TOTAL PERCENT ID\n"; ctime_t ttotal = stepData[AdvancedTimer::IdStep()].ttotal; for (unsigned int s=0; s<steps.size(); ++s) { StepData& data = stepData[steps[s]]; printVal(out, data.level); out << " "; printTime(out, data.tstart, data.numIt); out << " "; printVal(out, data.num, (s == 0) ? 1 : nbIter); out << " "; printTime(out, data.tmin); out << " "; printTime(out, data.tmax); out << " "; double mean = (double)data.ttotal / data.num; printTime(out, (ctime_t)mean); out << " "; printTime(out, (ctime_t)(sqrt((double)data.ttotal2/data.num - mean*mean))); out << " "; printTime(out, data.ttotal, (s == 0) ? 1 : nbIter); out << " "; printVal(out, 100.0*data.ttotal / (double) ttotal); out << " "; if (s == 0) out << "TOTAL"; else { for(int ii=0; ii<data.level; ii++) out<<"."; // indentation to show the hierarchy level out << steps[s]; } out << std::endl; } } if (!vals.empty()) { out << "\nValues Statistics :\n"; out << " NUM\t MIN\t MAX\t MEAN\t DEV\t TOTAL\tID\n"; for (unsigned int s=0; s<vals.size(); ++s) { ValData& data = valData[vals[s]]; printVal(out, data.num, nbIter); out << '\t'; printVal(out, data.vmin); out << '\t'; printVal(out, data.vmax); out << '\t'; double mean = data.vtotal / data.num; printVal(out, mean); out << '\t'; printVal(out, sqrt(data.vtotal2/data.num - mean*mean) ); out << '\t'; printVal(out, data.vtotal, nbIter); out << '\t'; out << vals[s]; out << std::endl; } } //out << "\n==== END ====\n"; out << std::endl; }