PageRenderTime 35ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 1ms

/indra/llcommon/llmetricperformancetester.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 336 lines | 226 code | 52 blank | 58 comment | 36 complexity | d6351d0b9a7d45dea12e762b2a408426 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llmetricperformancetester.cpp
  3. * @brief LLMetricPerformanceTesterBasic and LLMetricPerformanceTesterWithSession classes implementation
  4. *
  5. * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "linden_common.h"
  27. #include "indra_constants.h"
  28. #include "llerror.h"
  29. #include "llsdserialize.h"
  30. #include "llstat.h"
  31. #include "lltreeiterators.h"
  32. #include "llmetricperformancetester.h"
  33. //----------------------------------------------------------------------------------------------
  34. // LLMetricPerformanceTesterBasic : static methods and testers management
  35. //----------------------------------------------------------------------------------------------
  36. LLMetricPerformanceTesterBasic::name_tester_map_t LLMetricPerformanceTesterBasic::sTesterMap ;
  37. /*static*/
  38. void LLMetricPerformanceTesterBasic::cleanClass()
  39. {
  40. for (name_tester_map_t::iterator iter = sTesterMap.begin() ; iter != sTesterMap.end() ; ++iter)
  41. {
  42. delete iter->second ;
  43. }
  44. sTesterMap.clear() ;
  45. }
  46. /*static*/
  47. BOOL LLMetricPerformanceTesterBasic::addTester(LLMetricPerformanceTesterBasic* tester)
  48. {
  49. llassert_always(tester != NULL);
  50. std::string name = tester->getTesterName() ;
  51. if (getTester(name))
  52. {
  53. llerrs << "Tester name is already used by some other tester : " << name << llendl ;
  54. return FALSE;
  55. }
  56. sTesterMap.insert(std::make_pair(name, tester));
  57. return TRUE;
  58. }
  59. /*static*/
  60. void LLMetricPerformanceTesterBasic::deleteTester(std::string name)
  61. {
  62. name_tester_map_t::iterator tester = sTesterMap.find(name);
  63. if (tester != sTesterMap.end())
  64. {
  65. delete tester->second;
  66. sTesterMap.erase(tester);
  67. }
  68. }
  69. /*static*/
  70. LLMetricPerformanceTesterBasic* LLMetricPerformanceTesterBasic::getTester(std::string name)
  71. {
  72. // Check for the requested metric name
  73. name_tester_map_t::iterator found_it = sTesterMap.find(name) ;
  74. if (found_it != sTesterMap.end())
  75. {
  76. return found_it->second ;
  77. }
  78. return NULL ;
  79. }
  80. /*static*/
  81. // Return TRUE if this metric is requested or if the general default "catch all" metric is requested
  82. BOOL LLMetricPerformanceTesterBasic::isMetricLogRequested(std::string name)
  83. {
  84. return (LLFastTimer::sMetricLog && ((LLFastTimer::sLogName == name) || (LLFastTimer::sLogName == DEFAULT_METRIC_NAME)));
  85. }
  86. /*static*/
  87. LLSD LLMetricPerformanceTesterBasic::analyzeMetricPerformanceLog(std::istream& is)
  88. {
  89. LLSD ret;
  90. LLSD cur;
  91. while (!is.eof() && LLSDSerialize::fromXML(cur, is))
  92. {
  93. for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)
  94. {
  95. std::string label = iter->first;
  96. LLMetricPerformanceTesterBasic* tester = LLMetricPerformanceTesterBasic::getTester(iter->second["Name"].asString()) ;
  97. if(tester)
  98. {
  99. ret[label]["Name"] = iter->second["Name"] ;
  100. S32 num_of_metrics = tester->getNumberOfMetrics() ;
  101. for(S32 index = 0 ; index < num_of_metrics ; index++)
  102. {
  103. ret[label][ tester->getMetricName(index) ] = iter->second[ tester->getMetricName(index) ] ;
  104. }
  105. }
  106. }
  107. }
  108. return ret;
  109. }
  110. /*static*/
  111. void LLMetricPerformanceTesterBasic::doAnalysisMetrics(std::string baseline, std::string target, std::string output)
  112. {
  113. if(!LLMetricPerformanceTesterBasic::hasMetricPerformanceTesters())
  114. {
  115. return ;
  116. }
  117. // Open baseline and current target, exit if one is inexistent
  118. std::ifstream base_is(baseline.c_str());
  119. std::ifstream target_is(target.c_str());
  120. if (!base_is.is_open() || !target_is.is_open())
  121. {
  122. llwarns << "'-analyzeperformance' error : baseline or current target file inexistent" << llendl;
  123. base_is.close();
  124. target_is.close();
  125. return;
  126. }
  127. //analyze baseline
  128. LLSD base = analyzeMetricPerformanceLog(base_is);
  129. base_is.close();
  130. //analyze current
  131. LLSD current = analyzeMetricPerformanceLog(target_is);
  132. target_is.close();
  133. //output comparision
  134. std::ofstream os(output.c_str());
  135. os << "Label, Metric, Base(B), Target(T), Diff(T-B), Percentage(100*T/B)\n";
  136. for(LLMetricPerformanceTesterBasic::name_tester_map_t::iterator iter = LLMetricPerformanceTesterBasic::sTesterMap.begin() ;
  137. iter != LLMetricPerformanceTesterBasic::sTesterMap.end() ; ++iter)
  138. {
  139. LLMetricPerformanceTesterBasic* tester = ((LLMetricPerformanceTesterBasic*)iter->second) ;
  140. tester->analyzePerformance(&os, &base, &current) ;
  141. }
  142. os.flush();
  143. os.close();
  144. }
  145. //----------------------------------------------------------------------------------------------
  146. // LLMetricPerformanceTesterBasic : Tester instance methods
  147. //----------------------------------------------------------------------------------------------
  148. LLMetricPerformanceTesterBasic::LLMetricPerformanceTesterBasic(std::string name) :
  149. mName(name),
  150. mCount(0)
  151. {
  152. if (mName == std::string())
  153. {
  154. llerrs << "LLMetricPerformanceTesterBasic construction invalid : Empty name passed to constructor" << llendl ;
  155. }
  156. mValidInstance = LLMetricPerformanceTesterBasic::addTester(this) ;
  157. }
  158. LLMetricPerformanceTesterBasic::~LLMetricPerformanceTesterBasic()
  159. {
  160. }
  161. void LLMetricPerformanceTesterBasic::preOutputTestResults(LLSD* sd)
  162. {
  163. incrementCurrentCount() ;
  164. (*sd)[getCurrentLabelName()]["Name"] = mName ;
  165. }
  166. void LLMetricPerformanceTesterBasic::postOutputTestResults(LLSD* sd)
  167. {
  168. LLMutexLock lock(LLFastTimer::sLogLock);
  169. LLFastTimer::sLogQueue.push((*sd));
  170. }
  171. void LLMetricPerformanceTesterBasic::outputTestResults()
  172. {
  173. LLSD sd;
  174. preOutputTestResults(&sd) ;
  175. outputTestRecord(&sd) ;
  176. postOutputTestResults(&sd) ;
  177. }
  178. void LLMetricPerformanceTesterBasic::addMetric(std::string str)
  179. {
  180. mMetricStrings.push_back(str) ;
  181. }
  182. /*virtual*/
  183. void LLMetricPerformanceTesterBasic::analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current)
  184. {
  185. resetCurrentCount() ;
  186. std::string current_label = getCurrentLabelName();
  187. BOOL in_base = (*base).has(current_label) ;
  188. BOOL in_current = (*current).has(current_label) ;
  189. while(in_base || in_current)
  190. {
  191. LLSD::String label = current_label ;
  192. if(in_base && in_current)
  193. {
  194. *os << llformat("%s\n", label.c_str()) ;
  195. for(U32 index = 0 ; index < mMetricStrings.size() ; index++)
  196. {
  197. switch((*current)[label][ mMetricStrings[index] ].type())
  198. {
  199. case LLSD::TypeInteger:
  200. compareTestResults(os, mMetricStrings[index],
  201. (S32)((*base)[label][ mMetricStrings[index] ].asInteger()), (S32)((*current)[label][ mMetricStrings[index] ].asInteger())) ;
  202. break ;
  203. case LLSD::TypeReal:
  204. compareTestResults(os, mMetricStrings[index],
  205. (F32)((*base)[label][ mMetricStrings[index] ].asReal()), (F32)((*current)[label][ mMetricStrings[index] ].asReal())) ;
  206. break;
  207. default:
  208. llerrs << "unsupported metric " << mMetricStrings[index] << " LLSD type: " << (S32)(*current)[label][ mMetricStrings[index] ].type() << llendl ;
  209. }
  210. }
  211. }
  212. incrementCurrentCount();
  213. current_label = getCurrentLabelName();
  214. in_base = (*base).has(current_label) ;
  215. in_current = (*current).has(current_label) ;
  216. }
  217. }
  218. /*virtual*/
  219. void LLMetricPerformanceTesterBasic::compareTestResults(std::ofstream* os, std::string metric_string, S32 v_base, S32 v_current)
  220. {
  221. *os << llformat(" ,%s, %d, %d, %d, %.4f\n", metric_string.c_str(), v_base, v_current,
  222. v_current - v_base, (v_base != 0) ? 100.f * v_current / v_base : 0) ;
  223. }
  224. /*virtual*/
  225. void LLMetricPerformanceTesterBasic::compareTestResults(std::ofstream* os, std::string metric_string, F32 v_base, F32 v_current)
  226. {
  227. *os << llformat(" ,%s, %.4f, %.4f, %.4f, %.4f\n", metric_string.c_str(), v_base, v_current,
  228. v_current - v_base, (fabs(v_base) > 0.0001f) ? 100.f * v_current / v_base : 0.f ) ;
  229. }
  230. //----------------------------------------------------------------------------------------------
  231. // LLMetricPerformanceTesterWithSession
  232. //----------------------------------------------------------------------------------------------
  233. LLMetricPerformanceTesterWithSession::LLMetricPerformanceTesterWithSession(std::string name) :
  234. LLMetricPerformanceTesterBasic(name),
  235. mBaseSessionp(NULL),
  236. mCurrentSessionp(NULL)
  237. {
  238. }
  239. LLMetricPerformanceTesterWithSession::~LLMetricPerformanceTesterWithSession()
  240. {
  241. if (mBaseSessionp)
  242. {
  243. delete mBaseSessionp ;
  244. mBaseSessionp = NULL ;
  245. }
  246. if (mCurrentSessionp)
  247. {
  248. delete mCurrentSessionp ;
  249. mCurrentSessionp = NULL ;
  250. }
  251. }
  252. /*virtual*/
  253. void LLMetricPerformanceTesterWithSession::analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current)
  254. {
  255. // Load the base session
  256. resetCurrentCount() ;
  257. mBaseSessionp = loadTestSession(base) ;
  258. // Load the current session
  259. resetCurrentCount() ;
  260. mCurrentSessionp = loadTestSession(current) ;
  261. if (!mBaseSessionp || !mCurrentSessionp)
  262. {
  263. llerrs << "Error loading test sessions." << llendl ;
  264. }
  265. // Compare
  266. compareTestSessions(os) ;
  267. // Release memory
  268. if (mBaseSessionp)
  269. {
  270. delete mBaseSessionp ;
  271. mBaseSessionp = NULL ;
  272. }
  273. if (mCurrentSessionp)
  274. {
  275. delete mCurrentSessionp ;
  276. mCurrentSessionp = NULL ;
  277. }
  278. }
  279. //----------------------------------------------------------------------------------------------
  280. // LLTestSession
  281. //----------------------------------------------------------------------------------------------
  282. LLMetricPerformanceTesterWithSession::LLTestSession::~LLTestSession()
  283. {
  284. }