Made on Kubuntu
00001 #include <cstdio> 00002 #include <cstring> 00003 00004 #ifndef MINIINI_NO_STL 00005 #include <string> 00006 #include <vector> 00007 #endif 00008 00009 #include "../../miniini.h" 00010 #include "globals.h" 00011 #include "time.h" 00012 00014 00016 enum BenchmarkType 00017 { 00018 BT_STRING, 00019 BT_INT, 00020 BT_FLOAT, 00021 BT_BOOL, 00022 BT_MULTISTRING, 00023 BT_MULTIINT, 00024 BT_MULTIFLOAT, 00025 BT_MULTIBOOL, 00026 BT_STRINGS, 00027 BT_INTS, 00028 BT_FLOATS, 00029 BT_BOOLS, 00030 00031 BT_STRINGRULES, 00032 00033 BT_NONE 00034 }; 00035 00037 class ReadMark 00038 { 00039 private: 00040 00042 BenchmarkType Type; 00043 00045 bool STL; 00046 00048 char * BenchFile; 00049 00051 INISection * CurrentSection; 00052 00053 00054 public: 00055 00057 long double FileTime; 00058 00060 long double AllocTime; 00061 00063 long double LoadTime; 00064 00066 ReadMark(char * benchname, bool stl) 00067 :Type(BT_NONE) 00068 ,STL(stl) 00069 ,BenchFile(NULL) 00070 ,CurrentSection(NULL) 00071 ,FileTime(0.0) 00072 ,AllocTime(0.0) 00073 ,LoadTime(0.0) 00074 { 00075 #define SETTYPE(str, type, file)\ 00076 if(!strcmp(benchname, str))\ 00077 {\ 00078 size_t fnamelen = strlen(file) + 1;\ 00079 BenchFile = new char [fnamelen];\ 00080 Type = type;\ 00081 memcpy(BenchFile, file, fnamelen);\ 00082 }; 00083 SETTYPE("readstring", BT_STRING, "test/benchmark/string.ini"); 00084 SETTYPE("readint", BT_INT, "test/benchmark/int.ini"); 00085 SETTYPE("readfloat", BT_FLOAT, "test/benchmark/float.ini"); 00086 SETTYPE("readbool", BT_BOOL, "test/benchmark/bool.ini"); 00087 SETTYPE("readstringm", BT_MULTISTRING, "test/benchmark/stringm.ini"); 00088 SETTYPE("readintm", BT_MULTIINT, "test/benchmark/intm.ini"); 00089 SETTYPE("readfloatm", BT_MULTIFLOAT, "test/benchmark/floatm.ini"); 00090 SETTYPE("readboolm", BT_MULTIBOOL, "test/benchmark/boolm.ini"); 00091 SETTYPE("readstrings", BT_STRINGS, "test/benchmark/strings.ini"); 00092 SETTYPE("readints", BT_INTS, "test/benchmark/ints.ini"); 00093 SETTYPE("readfloats", BT_FLOATS, "test/benchmark/floats.ini"); 00094 SETTYPE("readbools", BT_BOOLS, "test/benchmark/bools.ini"); 00095 SETTYPE("readstringrules", BT_STRINGRULES, "test/benchmark/rulesmd2.ini"); 00096 #undef SETTYPE 00097 } 00098 00099 ~ReadMark() 00100 { 00101 delete [] BenchFile; 00102 } 00103 00104 //ReadXXX benchmarks over single section 00105 template<typename T, typename T2> 00106 void BenchRead(bool (INISection::*Read)(T, T2&) const) 00107 { 00108 while(CurrentSection->Next()) 00109 { 00110 T2 out; 00111 (CurrentSection->*Read)(CurrentSection->CurrentTag(), out); 00112 } 00113 } 00114 00117 #ifndef MINIINI_NO_STL 00118 #define BENCHREADMULTI(method, type, stltype)\ 00119 while(CurrentSection->Next())\ 00120 {\ 00121 if(STL)\ 00122 {\ 00123 std::vector<stltype> out;\ 00124 CurrentSection->method(CurrentSection->CurrentTag(), out);\ 00125 }\ 00126 else\ 00127 {\ 00128 unsigned elemcount = 1024;\ 00129 type * out = new type [elemcount];\ 00130 CurrentSection->method(CurrentSection->CurrentTag(), out, elemcount);\ 00131 delete [] out;\ 00132 }\ 00133 } 00134 #else 00135 #define BENCHREADMULTI(method, type, stltype)\ 00136 while(CurrentSection->Next())\ 00137 {\ 00138 unsigned elemcount = 1024;\ 00139 type * out = new type [elemcount];\ 00140 CurrentSection->method(CurrentSection->CurrentTag(), out, elemcount);\ 00141 delete [] out;\ 00142 } 00143 #endif 00144 00145 #ifndef MINIINI_NO_STL 00146 00151 #define BENCHREADARRAY(method, type, stltype)\ 00152 for(char tagname [] = "a"; tagname[0] <= 'z'; ++(tagname[0]))\ 00153 {\ 00154 if(STL)\ 00155 {\ 00156 std::vector<stltype> out;\ 00157 CurrentSection->method(std::string(tagname), out);\ 00158 }\ 00159 else\ 00160 {\ 00161 int elemcount;\ 00162 if(!CurrentSection->ReadInt(tagname, elemcount))\ 00163 {\ 00164 break;\ 00165 }\ 00166 type * out = new type [elemcount];\ 00167 CurrentSection->method(tagname, out, elemcount);\ 00168 delete [] out;\ 00169 }\ 00170 } 00171 #else 00172 #define BENCHREADARRAY(method, type, stltype)\ 00173 for(char tagname [] = "a"; tagname[0] <= 'z'; ++(tagname[0]))\ 00174 {\ 00175 int elemcount;\ 00176 if(!CurrentSection->ReadInt(tagname, elemcount))\ 00177 {\ 00178 break;\ 00179 }\ 00180 type * out = new type [elemcount];\ 00181 CurrentSection->method(tagname, out, elemcount);\ 00182 delete [] out;\ 00183 } 00184 #endif 00185 00187 bool Benchmark() 00188 { 00189 INIFile ini; 00190 if(!ini.OpenFile(BenchFile)) return false; 00191 while(ini.Next()) 00192 { 00193 CurrentSection = ini.GetSection(ini.GetSection("")->GetName()); 00194 switch(Type) 00195 { 00196 case BT_STRING: 00197 case BT_STRINGRULES: 00198 if(!STL) BenchRead<const char * const, const char *>(&INISection::ReadString); 00199 #ifndef MINIINI_NO_STL 00200 else BenchRead<const std::string &, std::string>(&INISection::ReadString); 00201 #endif 00202 break; 00203 case BT_INT: 00204 if(!STL) BenchRead<const char * const, int>(&INISection::ReadInt); 00205 #ifndef MINIINI_NO_STL 00206 else BenchRead<const std::string &, int>(&INISection::ReadInt); 00207 #endif 00208 break; 00209 case BT_FLOAT: 00210 if(!STL) BenchRead<const char * const, float>(&INISection::ReadFloat); 00211 #ifndef MINIINI_NO_STL 00212 else BenchRead<const std::string &, float>(&INISection::ReadFloat); 00213 #endif 00214 break; 00215 case BT_BOOL: 00216 if(!STL) BenchRead<const char * const, bool>(&INISection::ReadBool); 00217 #ifndef MINIINI_NO_STL 00218 else BenchRead<const std::string &, bool>(&INISection::ReadBool); 00219 #endif 00220 break; 00221 case BT_MULTISTRING: 00222 BENCHREADMULTI(ReadMultiString, const char *, std::string); 00223 break; 00224 case BT_MULTIINT: 00225 BENCHREADMULTI(ReadMultiInt, int, int); 00226 break; 00227 case BT_MULTIFLOAT: 00228 BENCHREADMULTI(ReadMultiFloat, float, float); 00229 break; 00230 case BT_MULTIBOOL: 00231 BENCHREADMULTI(ReadMultiBool, bool, bool); 00232 break; 00233 case BT_STRINGS: 00234 BENCHREADARRAY(ReadStrings, const char *, std::string); 00235 break; 00236 case BT_INTS: 00237 BENCHREADARRAY(ReadInts, int, int); 00238 break; 00239 case BT_FLOATS: 00240 BENCHREADARRAY(ReadFloats, float, float); 00241 case BT_BOOLS: 00242 BENCHREADARRAY(ReadBools, bool, bool); 00243 break; 00244 default: 00245 return false; 00246 break; 00247 } 00248 00249 } 00250 00251 #ifdef MINIINI_BENCH_EXTRA 00252 #ifdef linux 00253 FileTime = miniini_private::bench_filetime; 00254 AllocTime = miniini_private::bench_alloctime; 00255 LoadTime = miniini_private::bench_loadtime; 00256 #endif 00257 #endif 00258 00259 return true; 00260 } 00261 00262 #undef BENCHREADARRAY 00263 #undef BENCHREADMULTI 00264 00265 00266 private: 00267 00268 ReadMark(const ReadMark &); 00269 00270 void operator = (const ReadMark &); 00271 }; 00272 00273 void help() 00274 { 00275 puts 00276 ( 00277 "MiniINI benchmark\n" 00278 "Copyright (C) 2009-2010 Ferdinand Majerech\n" 00279 "Usage: bench [OPTIONS] [BENCHMARKS]\n" 00280 "Requires files to be present in test/benchmark for benchmarks to run\n" 00281 "Benchmarks and files they require:\n" 00282 " readstring string.ini\n" 00283 " readint int.ini\n" 00284 " readfloat float.ini\n" 00285 " readbool bool.ini\n" 00286 " readstringm stringm.ini\n" 00287 " readintm intm.ini\n" 00288 " readfloatm floatm.ini\n" 00289 " readboolm boolm.ini\n" 00290 " readstrings strings.ini\n" 00291 " readints ints.ini\n" 00292 " readfloats floats.ini\n" 00293 " readbools bools.ini\n" 00294 " readstringrules rulesmd2.ini\n" 00295 "Options:\n" 00296 " --stl STL API will be benchmarked instead of cstdlib API\n" 00297 " (for benchmarks where this applies)\n" 00298 #ifdef MINIINI_BENCH_EXTRA 00299 #ifdef linux 00300 " --extra Output extra benchmarking data\n" 00301 #endif 00302 #endif 00303 ); 00304 } 00305 00306 int main(int argc, char * argv []) 00307 { 00308 if(argc > 1) 00309 { 00310 #ifdef MINIINI_BENCH_EXTRA 00311 #ifdef linux 00312 long double timestart = miniini_private::GetTime(); 00313 long double filetime = 0.0; 00314 long double alloctime = 0.0; 00315 long double loadtime = 0.0; 00316 #endif 00317 #endif 00318 00319 bool needhelp = true; 00320 bool stl = false; 00321 bool extra = false; 00322 for(int arg = 1; arg < argc; ++arg) 00323 { 00324 if(!strcmp(argv[arg], "--stl")) 00325 { 00326 stl = true; 00327 #ifdef MINIINI_NO_STL 00328 stl = false; 00329 #endif 00330 } 00331 else 00332 if(!strcmp(argv[arg], "--extra")) 00333 { 00334 extra = true; 00335 } 00336 else 00337 { 00338 ReadMark bench(argv[arg], stl); 00339 if(!bench.Benchmark()) 00340 { 00341 printf("ERROR in benchmark %s\n", argv[arg]); 00342 return -1; 00343 } 00344 #ifdef MINIINI_BENCH_EXTRA 00345 #ifdef linux 00346 filetime += bench.FileTime; 00347 alloctime += bench.AllocTime; 00348 loadtime += bench.LoadTime; 00349 #endif 00350 #endif 00351 needhelp = false; 00352 } 00353 } 00354 if(needhelp) 00355 { 00356 help(); 00357 return -1; 00358 } 00359 #ifdef MINIINI_BENCH_EXTRA 00360 #ifdef linux 00361 long double totaltime = miniini_private::GetTime() - timestart; 00362 if(extra) 00363 { 00364 printf("TESTUTIL Total_time_ms = %Lf\nTESTUTIL File_time_ms = %Lf\n" 00365 "TESTUTIL File_time_ratio = %Lf\nTESTUTIL Alloc_time_ms = %Lf\n" 00366 "TESTUTIL Alloc_time_ratio = %Lf\nTESTUTIL Load_time_ms = %Lf\n" 00367 "TESTUTIL Load_time_ratio = %Lf\n", 00368 totaltime * 1000.0, filetime * 1000.0, 00369 filetime / totaltime , alloctime * 1000.0, 00370 alloctime / totaltime , loadtime * 1000.0, 00371 loadtime / totaltime ); 00372 } 00373 #endif 00374 #endif 00375 } 00376 else 00377 { 00378 help(); 00379 return -4; 00380 } 00381 return 0; 00382 } 00383