fork(13) download
  1. #if _MSC_VER
  2. #pragma warning(disable: 4996) // _CRT_SECURE_NO_WARNINGS
  3. #include <intrin.h>
  4. #else
  5. #include <x86intrin.h>
  6. #endif
  7.  
  8. #include <iostream>
  9. #include <stdio.h> // printf
  10. #include <string.h> // memcmp
  11. #define min_( a, b ) ( (a) < (b) ? (a) : (b) )
  12.  
  13. //------------------------------+---------------------------------------------------------------
  14.  
  15. #ifndef SYS_BITS
  16. #define CHAR_BITS 8
  17. #define SYS_BYTES sizeof( std::size_t )
  18. #define SYS_BITS ( SYS_BYTES * CHAR_BITS )
  19. #endif
  20.  
  21. //------------------------------+---------------------------------------------------------------
  22.  
  23. using ON_RUN = void( & )( void* );
  24. using ON_PREPARE = void( & )( void* );
  25. using ON_COMPARE = bool( & )( void*, void*, std::size_t );
  26.  
  27. //------------------------------+---------------------------------------------------------------
  28. // BENCH 에 의해서만 접근되기 때문에 모든 멤버가 private ( class default ) 입니다
  29. class RUNNER
  30. {
  31. friend class BENCH;
  32. const char* name;
  33. unsigned long long elapsed;
  34. const ON_RUN on_run;
  35. void* result;
  36.  
  37. RUNNER( const char* name, ON_RUN&& on_run, void* result )
  38. : name( name )
  39. , on_run( on_run )
  40. , elapsed( -1 )
  41. , result( result )
  42. {
  43. }
  44.  
  45. void run()
  46. {
  47. auto begin = __rdtsc();
  48. on_run( result );
  49. elapsed = min_( elapsed, __rdtsc() - begin );
  50. }
  51. };
  52. ///-----------------------------+---------------------------------------------------------------
  53.  
  54. #include <vector>
  55.  
  56. class BENCH
  57. {
  58. private:
  59. const char* title;
  60. std::vector< RUNNER* > runners;
  61. ON_PREPARE on_prepare;
  62. ON_COMPARE on_compare;
  63. void* answer;
  64. std::size_t answer_size;
  65. const unsigned int trial;
  66.  
  67. public:
  68. BENCH( const char* title, const int trial,
  69. ON_PREPARE& prepare, ON_COMPARE& compare
  70. )
  71. : title( title )
  72. , trial( trial )
  73. , on_prepare( prepare )
  74. , on_compare( compare )
  75. {
  76. };
  77. ~BENCH()
  78. {
  79. for( auto runner : runners )
  80. delete[] runner;
  81. runners.clear();
  82. }
  83.  
  84. auto record( unsigned int index ) const
  85. {
  86. return runners[ index ]->elapsed;
  87. }
  88.  
  89. auto runner_count() const
  90. {
  91. return runners.size();
  92. }
  93.  
  94. void solution( ON_RUN& correct_function,
  95. void* result, const std::size_t bytes )
  96. {
  97. answer = result;
  98. answer_size = bytes;
  99. on_prepare( result );
  100. correct_function( result );
  101. }
  102.  
  103. template< typename T >
  104. void solution( ON_RUN& correct_function,
  105. T& result, const std::size_t bytes )
  106. {
  107. solution( correct_function, &result, bytes );
  108. }
  109.  
  110. void add( const char* name, ON_RUN& on_run, void* result )
  111. {
  112. runners.emplace_back( new RUNNER( name, on_run, result ) );
  113. }
  114.  
  115. template< typename T >
  116. void add( const char* name, ON_RUN& on_run, T& result )
  117. {
  118. add( name, on_run, &result );
  119. }
  120.  
  121. void run() const
  122. {
  123. if( runners.empty() )
  124. return;
  125.  
  126. printf( "\n < %d bits %d trial > %s\n", (int)SYS_BITS, trial, title );
  127. puts( " ----------------+---------------------------------+-----------------------" );
  128. puts( " | CHECKER | function name | minimum clocks |" );
  129. puts( " ----------------+---------------------------------+-----------------------" );
  130.  
  131. unsigned long long min_clocks = -1;
  132. unsigned long long max_clocks = 0;
  133. RUNNER* min_runner = runners[ 0 ];
  134. RUNNER* max_runner = runners[ 0 ];
  135.  
  136. for( const auto runner : runners )
  137. {
  138. int pass_count = 0;
  139. for( unsigned int i = 0; i < trial; ++i )
  140. {
  141. on_prepare( runner->result );
  142. runner->run();
  143. pass_count += on_compare( runner->result, answer, answer_size );
  144. }
  145.  
  146. if( min_clocks > runner->elapsed )
  147. {
  148. min_runner = runner;
  149. min_clocks = runner->elapsed;
  150. }
  151. if( max_clocks < runner->elapsed )
  152. {
  153. max_runner = runner;
  154. max_clocks = runner->elapsed;
  155. }
  156.  
  157. char temp[ 14 ];
  158. if( trial == pass_count )
  159. sprintf( temp, " PASSED" );
  160. else
  161. sprintf( temp, "FAILED%7d", trial - pass_count );
  162.  
  163. printf( " [ %s ] %32s %15llu clocks\n", temp, runner->name, runner->elapsed );
  164. }
  165. puts( " --------------------------------------------------------------------------" );
  166. printf( " Winner is %s ( %.2f times faster )\n\n",
  167. min_runner->name, float( max_clocks ) / min_clocks );
  168. }
  169. };
  170.  
  171. #define FUN( function_name ) #function_name, function_name
  172.  
  173. //==============================================================================================
  174. //------------------------------+---------------------------------------------------------------
  175.  
  176. using SOURCE = char;
  177. using RESULT = char;
  178.  
  179. SOURCE src1[ 256 ];
  180. SOURCE src2[ 256 ];
  181.  
  182. constexpr std::size_t SIZE = sizeof src1 / sizeof *src1;
  183.  
  184. RESULT dst0[ SIZE ], dst1[ SIZE ], dst2[ SIZE ], dst3[ SIZE ], dst4[ SIZE ],
  185. dst5[ SIZE ], dst6[ SIZE ], dst7[ SIZE ], dst8[ SIZE ], dst9[ SIZE ];
  186.  
  187. //------------------------------+---------------------------------------------------------------
  188. // 테스트전에 불려질 초기화 함수
  189. void prepare( void* result )
  190. {
  191. strcpy( src1, "___#*U#U*$@*#UU@TDKDAJKFKDKJFFJKbcdefghijklmnopqrstuvwxyz");
  192. strcpy( src2, "___#*U#U*$@*#UU@TDKDJKFKDKJFFJKbcdefghijklmnopqrstuvwxyz");
  193. // memcpy( result, src, sizeof src );
  194. }
  195. // 테스트후에 불려질 점검 함수
  196. bool compare( void* result, void* answer, std::size_t bytes )
  197. {
  198. return memcmp( result, answer, bytes ) == 0;
  199. }
  200. //------------------------------+---------------------------------------------------------------
  201. // 테스트할 함수들
  202. //------------------------------+---------------------------------------------------------------
  203.  
  204. namespace hsoo
  205. {
  206.  
  207. int is_pangram(const char *str)
  208. {
  209. int i = *str;
  210. int j = 1;
  211. for( ; i < 10000; ++i ) j+=i;
  212. return j;
  213. }
  214.  
  215.  
  216. void run( void* dst )
  217. {
  218. bool* b = (bool*)dst;
  219. b[0] = is_pangram( src1 );
  220. b[1] = is_pangram( src2 );
  221. }
  222.  
  223. }
  224. //------------------------------+---------------------------------------------------------------
  225.  
  226. namespace cose
  227. {
  228.  
  229. const unsigned int alphaset[ 128 ] =
  230. {
  231. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  232. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  233. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  234. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  235. 0, 1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6,
  236. 1 << 7, 1 << 8, 1 << 9, 1 << 10, 1 << 11, 1 << 12, 1 << 13, 1 << 14,
  237. 1 << 15, 1 << 16, 1 << 17, 1 << 18, 1 << 19, 1 << 20, 1 << 21, 1 << 22,
  238. 1 << 23, 1 << 24, 1 << 25, 0, 0, 0, 0, 0,
  239. 0, 1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6,
  240. 1 << 7, 1 << 8, 1 << 9, 1 << 10, 1 << 11, 1 << 12, 1 << 13, 1 << 14,
  241. 1 << 15, 1 << 16, 1 << 17, 1 << 18, 1 << 19, 1 << 20, 1 << 21, 1 << 22,
  242. 1 << 23, 1 << 24, 1 << 25, 0, 0, 0, 0, 0,
  243. };
  244.  
  245. bool is_pangram( char* str )
  246. {
  247. unsigned int mux = 0;
  248. while( *str ) mux |= alphaset[ *str++ ];
  249. return mux == 0x03FFFFFF;
  250. }
  251.  
  252. void run( void* dst )
  253. {
  254. bool* b = (bool*)dst;
  255. b[0] = is_pangram( src1 );
  256. b[1] = is_pangram( src2 );
  257. }
  258.  
  259. }
  260.  
  261. //------------------------------+---------------------------------------------------------------
  262. #include <iostream>
  263.  
  264. using namespace std;
  265.  
  266. int main()
  267. {
  268. BENCH bench( "pangram", 1000000, prepare, compare );
  269. bench.solution( cose::run, dst0, sizeof dst0 );
  270. bench.add( FUN( cose::run ), dst1 );
  271. bench.add( FUN( hsoo::run ), dst8 );
  272. /*
  273.   bench.add( FUN( adun::run ), dst2 );
  274.   bench.add( FUN( asdf::run ), dst3 );
  275.   bench.add( FUN( powerup::run ), dst4 );
  276.   bench.add( FUN( oo_203_84::run ), dst5 );
  277.   bench.add( FUN( f::run ), dst6 );
  278.   bench.add( FUN( wizard::run ), dst7 );
  279. */
  280. bench.run();
  281.  
  282. getchar();
  283. return 0;
  284. }
Success #stdin #stdout 6.05s 15240KB
stdin
Standard input is empty
stdout
   < 64 bits 1000000 trial >    pangram
   ----------------+---------------------------------+-----------------------
   |    CHECKER    |          function name          |    minimum clocks    |
   ----------------+---------------------------------+-----------------------
   [        PASSED ]                        cose::run             163 clocks
   [ FAILED1000000 ]                        hsoo::run           17190 clocks
   --------------------------------------------------------------------------
   Winner is cose::run  ( 105.46 times faster )