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