/** * @file test3.cpp * @brief 文字列表示での文字列処理の時間計測. */ #include <stddef.h> #include <cstddef> #include <stdlib.h> #ifdef MALLOC_CHK #include "malloc_chk.h" #endif #include <stdio.h> #include <assert.h> #include <string.h> #include <sstream> #include <streambuf> #include <string> #include <iomanip> #ifdef _WIN32 #include <windows.h> #endif #include "StrzStream.h" using namespace std; // =========================================================================== // 時間計測関係 #ifdef _WIN32 #include <windows.h> typedef unsigned __int64 PerfCnt_tick_t; PerfCnt_tick_t PerfCnt_getTick() { PerfCnt_tick_t c; QueryPerformanceCounter((LARGE_INTEGER*)&c); return c; } PerfCnt_tick_t PerfCnt_tickPerSec() { static PerfCnt_tick_t s = 0; if (!s) QueryPerformanceFrequency((LARGE_INTEGER*)&s); return s; } #elif defined LINUX #include <sys/resource.h> typedef double PerfCnt_tick_t; PerfCnt_tick_t PerfCnt_getTick() { struct rusage t; getrusage(RUSAGE_SELF, &t); return t.ru_utime.tv_sec * 1000000.0 + t.ru_utime.tv_usec; } #define PerfCnt_tickPerSec() 1000000.0 #else #include <time.h> typedef clock_t PerfCnt_tick_t; #define PerfCnt_getTick() clock() #define PerfCnt_tickPerSec() CLOCKS_PER_SEC #endif // =========================================================================== void dummy_puts(const char* msg); // 空関数だが最適化させないため、別ファイル. void dummy_puts_set_mode(int mode); // sprintfを使った場合. void test_sprintf(const char* fname, unsigned line, unsigned long long val) { char buf[1024]; sprintf(buf, "%-24s(%10d) : test %#016llx\n", fname, line, val); dummy_puts(buf); } static CharAryStream<1024> s_charAryStream; // 固定バッファのみのstream void test_chararystream(const char* fname, unsigned line, unsigned long long val) { s_charAryStream.clear_buf(); s_charAryStream << setw(24) << left << fname << right << '(' << setw(10) << line << ") : test " << setfill('0') << setw(16) << hex << showbase << val << '\n'; dummy_puts( s_charAryStream.c_str() ); } static stringstream s_stringstream; // stringstream を予め生成して使った場合. void test_stringstream(const char* fname, unsigned line, unsigned long long val) { s_stringstream.str(std::string("")); s_stringstream << setw(24) << left << fname << right << '(' << setw(10) << line << ") : test " << setfill('0') << setw(16) << hex << showbase << val << '\n'; dummy_puts( s_stringstream.str().c_str() ); } // =========================================================================== // 計測&チェック typedef void (*test_print_func_t)(const char* fname, unsigned line, unsigned long long val); double test(test_print_func_t test_print, size_t size, unsigned flags, const char* ttl) { unsigned char verboss = flags & 1; if (verboss) { fprintf(stderr, "\t%s:start\n", ttl); dummy_puts_set_mode(verboss); //size = 1; #ifdef MALLOC_CHK my_malloc_count_init(); #endif } // ダミー表示=文字列処理時間 の計測. PerfCnt_tick_t start_time = PerfCnt_getTick(); // 計測開始 for (unsigned j = 0; j < size; ++j) { test_print("abcdefghijk.lmn", 123456, 0xFFFFFF11ffULL ); } PerfCnt_tick_t elapsed = PerfCnt_getTick() - start_time; // 計測終了 double e = elapsed * 1.0 / (PerfCnt_tickPerSec() * size); if (verboss) { fprintf(stderr, "\t%s:end (%f)\n", ttl, e * 1000000.0); #ifdef MALLOC_CHK my_malloc_count_disp(); #endif } return e; // ソート時間. } void test_all(unsigned size, unsigned v) { const char* nm[32] = {0}; double elaped[32] = { 0 }; fprintf(stderr, "\nダミーメッセージの文字列処理時間の計測\n" ); if (v) fprintf(stderr, "出力回数 %9d (の平均)\n", size); // 各ソートのチェック. unsigned k = 0; { nm[k] = "sprintf " ; elaped[k] = test(test_sprintf , size, v, nm[k]); ++k; nm[k] = "CharAryStream" ; elaped[k] = test(test_chararystream, size, v, nm[k]); ++k; nm[k] = "stringstream " ; elaped[k] = test(test_stringstream , size, v, nm[k]); ++k; } // 実行結果の出力 printf("\n*** ダミーメッセージの%d回の平均の文字列処理時間(μ秒)\n", size); printf("\n"); for (unsigned j = 0; j < 32; ++j) { if (nm[j] == 0) continue; printf(",%-21s ,", nm[j]); double e = elaped[j]*1000000.0; if (e > 0) printf("%12.3f,", e); else printf("%12s,", "---"); printf("\n"); } } int main(int argc, char* argv[]) { unsigned size = 1; //100000; unsigned v = 0; // オプションチェック for (int i = 1; i < argc; ++i) { if (strncmp(argv[i], "-c",2) == 0) { // ループ回数. size = strtol(argv[i]+2,0,0); if (size < 1) size = 1; } else if (strcmp(argv[i], "-v") == 0) { v = 1; } } test_all(size, v); return 0; }