00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "stats.h"
00023 #ifdef ENABLE_STATS
00024 #include <SDL.h>
00025 #include <map>
00026 #include <vector>
00027 #include <list>
00028 #include <algorithm>
00029 #include <iostream>
00030 #include <iomanip>
00031 #include <fstream>
00032
00033 typedef uint StatTime_t;
00034
00035 class StatOutputItem
00036 {
00037 public:
00038 StatOutputItem(const std::string &p_function)
00039 : function(p_function), total(0), min(0), max(0)
00040 {}
00041 bool operator< (const StatOutputItem& b) const
00042 {
00043 return total > b.total;
00044 }
00045 std::string function;
00046 uint count;
00047 StatTime_t total;
00048 StatTime_t min;
00049 StatTime_t max;
00050 };
00051
00052
00053 StatTime_t StatGetTimer()
00054 {
00055 return SDL_GetTicks();
00056 }
00057
00058 class StatItem
00059 {
00060 public:
00061 std::vector<StatTime_t> time;
00062 typedef std::vector<StatTime_t>::const_iterator time_it;
00063 uint count;
00064 StatTime_t last_time;
00065 StatItem() : count(0) { last_time = StatGetTimer(); }
00066 };
00067
00068 std::map<std::string, StatItem> stats;
00069 typedef std::map<std::string, StatItem>::iterator stats_it;
00070
00071 void StatStart(const std::string &function)
00072 {
00073 stats_it it = stats.find(function);
00074 StatItem &item = (it != stats.end()) ? it->second : stats[function];
00075 item.count++;
00076 item.last_time = StatGetTimer();
00077 }
00078
00079 void StatStop(const std::string &function)
00080 {
00081 stats_it it = stats.find(function);
00082 if (it == stats.end()) return;
00083 it->second.time.push_back(StatGetTimer() - it->second.last_time);
00084 }
00085
00086 StatTime_t ComputeStat(std::list<StatOutputItem> &table)
00087 {
00088 std::list<StatOutputItem>::iterator table_it;
00089 stats_it it = stats.begin(), end=stats.end();
00090 StatTime_t total_time = 0;
00091 table.clear();
00092 for (; it != end; ++it)
00093 {
00094 StatOutputItem item(it->first);
00095 item.count = it->second.time.size();
00096 StatItem::time_it time = it->second.time.begin(), time_end=it->second.time.end();
00097 if (time != time_end)
00098 {
00099 item.min = *time;
00100 item.max = *time;
00101 for (; time != time_end; ++time)
00102 {
00103 item.total += *time;
00104 item.min = std::min(item.min, *time);
00105 item.max = std::max(item.max, *time);
00106 }
00107 }
00108 table.push_back(item);
00109 total_time += item.total;
00110 }
00111 if (total_time == 0) total_time = 1;
00112 return total_time;
00113 }
00114
00115 std::string str2xml(const std::string &str)
00116 {
00117
00118
00119
00120
00121 return str;
00122 }
00123
00124 void DoSaveStatToXML(const std::string &filename,
00125 std::list<StatOutputItem> &table,
00126 StatTime_t total_time)
00127 {
00128 std::basic_ofstream<char> file(filename.c_str(), std::ios_base::out);
00129 if (!file)
00130 {
00131 std::cerr << "Can not create/open file \"" << filename << "\" to store statistics." << std::endl;
00132 }
00133
00134 std::list<StatOutputItem>::const_iterator it=table.begin(), end=table.end();
00135 file << "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>\n";
00136 file << "<stats total_time=\"" << total_time << "\">\n";
00137 file.setf(std::ios_base::fixed);
00138 file.precision(2);
00139 for (; it != end; ++it)
00140 {
00141 file
00142 << " <item function=\"" << it->function
00143 << "\" count=\"" << it->count
00144 << "\" total=\"" << it->total
00145 << "\" min=\"" << it->min
00146 << "\" max=\"" << it->max
00147 << "\" />\n";
00148 }
00149 file << "</stats>\n";
00150 file.close();
00151 }
00152
00153 void SaveStatToXML(const std::string &filename)
00154 {
00155 std::list<StatOutputItem> table;
00156 StatTime_t total_time = ComputeStat(table);
00157 table.sort();
00158 DoSaveStatToXML(filename, table, total_time);
00159 }
00160
00161 #endif // ENABLE_STATS