tictoc.cpp
Go to the documentation of this file.
00001 /*
00002  * tictoc.c
00003  *
00004  *  Created on: May 29, 2009
00005  *      Author: abachrac
00006  */
00007 
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <unistd.h>
00011 #include <string.h>
00012 #include <sys/time.h>
00013 
00014 #include <map>
00015 #include <vector>
00016 #include <string>
00017 #include <algorithm>
00018 
00019 #include "tictoc.hpp"
00020 
00021 //simple, quick and dirty profiling tool...
00022 
00023 namespace fovis
00024 {
00025 
00026 static int64_t _timestamp_now()
00027 {
00028     struct timeval tv;
00029     gettimeofday (&tv, NULL);
00030     return (int64_t) tv.tv_sec * 1000000 + tv.tv_usec;
00031 }
00032 
00033 static bool
00034 _tictoc_t_avgTimeCompare(const tictoc_t* t1, const tictoc_t* t2)
00035 {
00036     if (t1->numCalls < 1)
00037         return 1;
00038     else if (t2->numCalls < 1)
00039         return 0;
00040     else
00041         return (t1->totalT / t1->numCalls) < (t2->totalT / t2->numCalls);
00042 }
00043 static bool
00044 _tictoc_t_totalTimeCompare(const tictoc_t* t1, const tictoc_t* t2)
00045 {
00046     if (t1->numCalls < 1)
00047         return 1;
00048     else if (t2->numCalls < 1)
00049         return 0;
00050     else
00051         return t1->totalT < t2->totalT;
00052 }
00053 static bool
00054 _tictoc_t_maxTimeCompare(const tictoc_t* t1, const tictoc_t* t2)
00055 {
00056     if (t1->numCalls < 1)
00057         return 1;
00058     else if (t2->numCalls < 1)
00059         return 0;
00060     else
00061         return t1->max < t2->max;
00062 }
00063 static bool
00064 _tictoc_t_minTimeCompare(const tictoc_t* t1, const tictoc_t* t2)
00065 {
00066     if (t1->numCalls < 1)
00067         return 1;
00068     else if (t2->numCalls < 1)
00069         return 0;
00070     else
00071         return t1->min > t2->min;
00072 }
00073 static bool
00074 _tictoc_t_emaTimeCompare(const tictoc_t* t1, const tictoc_t* t2)
00075 {
00076     if (t1->numCalls < 1)
00077         return 1;
00078     else if (t2->numCalls < 1)
00079         return 0;
00080     else
00081         return t1->ema < t2->ema;
00082 }
00083 
00084 static bool
00085 _tictoc_t_alphCompare(const tictoc_t* t1, const tictoc_t* t2)
00086 {
00087     if (t1->numCalls < 1)
00088         return 1;
00089     else if (t2->numCalls < 1)
00090         return 0;
00091     else
00092         return strcmp(t1->description.c_str(), t2->description.c_str());
00093 }
00094 
00095 static int _tictoc_enabled = 1;
00096 static int _tictoc_initialized = 0;
00097 typedef std::map<std::string, tictoc_t> TictocMap;
00098 static TictocMap _tictoc_map;
00099 
00100 static void
00101 _initializeTictoc()
00102 {
00103     const char *tmp;
00104     tmp = getenv(FOVIS_TICTOC_ENV);
00105     if (tmp != NULL) {
00106         _tictoc_enabled = 1;
00107     } else {
00108         _tictoc_enabled = 0;
00109     }
00110 }
00111 
00112 int64_t
00113 tictoc(const char *description)
00114 {
00115     return tictoc_full(description, .01, NULL);
00116 }
00117 
00118 int64_t
00119 tictoc_full(const char *description, double ema_alpha, int64_t * ema)
00120 {
00121     if (!_tictoc_enabled)
00122         return 0;
00123 
00124     int64_t ret = 0;
00125 
00126     if (!_tictoc_initialized) {
00127         _tictoc_initialized = 1;
00128         _initializeTictoc();
00129         if (!_tictoc_enabled) {
00130             return 0;
00131         }
00132 
00133     }
00134 
00135     int64_t tictoctime = _timestamp_now();
00136     TictocMap::iterator eiter = _tictoc_map.find(description);
00137     if(eiter == _tictoc_map.end()) {
00138         //first time around, allocate and set the timer goin...
00139         tictoc_t entry;
00140         entry.flag = 1;
00141         entry.t = tictoctime;
00142         entry.totalT = 0;
00143         entry.numCalls = 0;
00144         entry.max = -1e15;
00145         entry.min = 1e15;
00146         entry.ema = 0;
00147         entry.description = description;
00148         _tictoc_map[description] = entry;
00149         ret = tictoctime;
00150     } else if (eiter->second.flag == 0) {
00151         eiter->second.flag = 1;
00152         eiter->second.t = tictoctime;
00153         ret = tictoctime;
00154     } else {
00155         eiter->second.flag = 0;
00156         int64_t dt = tictoctime - eiter->second.t;
00157         eiter->second.numCalls++;
00158         eiter->second.totalT += dt;
00159         if (dt < eiter->second.min)
00160             eiter->second.min = dt;
00161         if (dt > eiter->second.max)
00162             eiter->second.max = dt;
00163         eiter->second.ema = (1.0 - ema_alpha) * eiter->second.ema + ema_alpha * dt;
00164         if (ema != NULL)
00165             *ema = eiter->second.ema;
00166         ret = dt;
00167     }
00168     return ret;
00169 }
00170 
00171 void
00172 tictoc_get_stats(std::vector<tictoc_t> *stats)
00173 {
00174     if (!_tictoc_enabled) {
00175       return;
00176     }
00177     TictocMap::iterator iter = _tictoc_map.begin();
00178     TictocMap::iterator eiter = _tictoc_map.end();
00179     for(; iter != eiter; ++iter) {
00180       stats->push_back(iter->second);
00181     }
00182 }
00183 
00184 void
00185 tictoc_print_stats(tictoc_sort_type_t sortType)
00186 {
00187   if (!_tictoc_enabled) {
00188     return;
00189   }
00190   TictocMap::iterator iter = _tictoc_map.begin();
00191   TictocMap::iterator eiter = _tictoc_map.end();
00192   std::vector<const tictoc_t*> entries;
00193   for(; iter != eiter; ++iter) {
00194     entries.push_back(&iter->second);
00195   }
00196 
00197     printf("\n--------------------------------------------\n");
00198     printf("tictoc Statistics, sorted by ");
00199     switch (sortType)
00200     {
00201       case TICTOC_AVG:
00202         printf("average time\n");
00203         std::sort(entries.begin(), entries.end(), _tictoc_t_avgTimeCompare);
00204         break;
00205       case TICTOC_MIN:
00206         printf("min time\n");
00207         std::sort(entries.begin(), entries.end(), _tictoc_t_minTimeCompare);
00208         break;
00209       case TICTOC_MAX:
00210         printf("max time\n");
00211         std::sort(entries.begin(), entries.end(), _tictoc_t_maxTimeCompare);
00212         break;
00213       case TICTOC_EMA:
00214         printf("EMA time\n");
00215         std::sort(entries.begin(), entries.end(), _tictoc_t_emaTimeCompare);
00216         break;
00217       case TICTOC_TOTAL:
00218         printf("total time\n");
00219         std::sort(entries.begin(), entries.end(), _tictoc_t_totalTimeCompare);
00220         break;
00221       case TICTOC_ALPHABETICAL:
00222         printf("alphabetically\n");
00223         std::sort(entries.begin(), entries.end(), _tictoc_t_alphCompare);
00224         break;
00225       default:
00226         fprintf(stderr, "WARNING: invalid sort type in tictoc, using AVG\n");
00227         std::sort(entries.begin(), entries.end(), _tictoc_t_avgTimeCompare);
00228         break;
00229     }
00230     printf("--------------------------------------------\n");
00231     for(std::vector<const tictoc_t*>::iterator iter=entries.begin();
00232         iter != entries.end(); ++iter) {
00233       const tictoc_t* tt = *iter;
00234       if (tt->numCalls < 1)
00235         return;
00236       double totalT = (double) tt->totalT / 1.0e6;
00237       double avgT = ((double) tt->totalT / (double) tt->numCalls) / 1.0e6;
00238       double minT = (double) tt->min / 1.0e6;
00239       double maxT = (double) tt->max / 1.0e6;
00240       double emaT = (double) tt->ema / 1.0e6;
00241       printf("%30s: \t numCalls = %d \t totalT=%.2f \t avgT=%.4f \t minT=%.4f \t maxT=%.4f \t emaT=%.4f\n",
00242           tt->description.c_str(), tt->numCalls, totalT, avgT, minT, maxT, emaT);
00243     }
00244     printf("--------------------------------------------\n");
00245 }
00246 
00247 }


libfovis
Author(s): Albert Huang, Maurice Fallon
autogenerated on Thu Jun 6 2019 20:16:12