src/tool/stats.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *  Wormux is a convivial mass murder game.
00003  *  Copyright (C) 2001-2004 Lawrence Azzoug.
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00018  ******************************************************************************
00019  * Statistics. 
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 // TODO
00118 //    str.replace("&", "&amp;");
00119 //    str.replace("<", "&lt;");
00120 //    str.replace(">", "&gt;");
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

Generated on Mon Jan 1 13:10:59 2007 for Wormux by  doxygen 1.4.7