fork download
  1. #include "stdafx.h"
  2. #include <stdio.h>
  3. #include <tchar.h>
  4. #include <windows.h>
  5.  
  6. struct FOO{ int a; int *b; long c; char *d; };
  7.  
  8. __declspec(noinline)
  9. void __stdcall foo1(FOO h){
  10. printf("", h.a, h.b, h.c, h.d);
  11. }
  12.  
  13. __declspec(noinline)
  14. void __stdcall foo2(int a, int *b, long c, char *d){
  15. printf("", a, b, c, d);
  16. }
  17.  
  18. typedef void (__stdcall *FOO1)(FOO h);
  19. typedef void (__stdcall *FOO2)(int a, void *b, long c, char *d);
  20.  
  21. double QPFInit(){
  22. LARGE_INTEGER li;
  23. QueryPerformanceFrequency(&li);
  24. return (double)li.QuadPart;
  25. }
  26.  
  27. double QPT(){
  28. static double qpf = QPFInit();
  29. LARGE_INTEGER li;
  30. QueryPerformanceCounter(&li);
  31. return li.QuadPart / qpf;
  32. }
  33.  
  34. static const size_t cnt1 = 10000;
  35. static const size_t cnt2 = 10000;
  36. static double times[cnt2];
  37.  
  38. int compare(const void *v1, const void *v2){
  39. auto &t1 = *(const double*)v1;
  40. auto &t2 = *(const double*)v2;
  41. if(t1 < t2){
  42. return -1;
  43. }else if(t1 > t2){
  44. return 1;
  45. }else{
  46. return 0;
  47. }
  48. }
  49.  
  50. double bench(const char *name, void (*func)()){
  51. printf("%s: ", name);
  52. for(size_t t = 0; t < cnt2; ++t){
  53. auto start = QPT();
  54. for(size_t s = 0; s < cnt1; ++s){
  55. func();
  56. }
  57. auto stop = QPT();
  58. times[t] = (stop - start) / cnt1;
  59. }
  60. qsort(times, cnt2, sizeof(double), compare);
  61. double sum = 0;
  62. for(size_t t = cnt2 / 4, e = t + cnt2 / 2; t < e; ++t){
  63. sum += times[t];
  64. }
  65. sum /= cnt2 / 2;
  66. printf("%g\n", sum);
  67. return sum;
  68. }
  69.  
  70. FOO h = { 6, &h.a, 8, "efd", };
  71.  
  72. void printf_test(){
  73. printf("", h.a, h.b, h.c, h.d);
  74. }
  75.  
  76. void foo1_test(){
  77. foo1(h);
  78. }
  79.  
  80. void foo2_test(){
  81. foo2(h.a, h.b, h.c, h.d);
  82. }
  83.  
  84. int _tmain(int argc, _TCHAR* argv[]){
  85.  
  86. auto printf_time = bench("printf", printf_test);
  87. auto foo1_time = bench("foo1", foo1_test);
  88. auto foo2_time = bench("foo2", foo2_test);
  89.  
  90. //foo1(h);
  91. ((FOO1)foo2)(h); //これがあるとfoo2がfoo1に統合される
  92.  
  93. //foo2(h.a, h.b, h.c, h.d);
  94. //((FOO2)foo1)(h.a, h.b, h.c, h.d);
  95.  
  96. return 0;
  97. }
  98.  
  99. /*
  100.  
  101. ---------------------------------------------------------------------------
  102. Releaseビルド
  103. ((FOO1)foo2)(h); //これがあるとfoo2がfoo1に統合される
  104.  
  105.  
  106. //統合されたfoo1とfoo2関数本体
  107. __declspec(noinline)
  108. void __stdcall foo2(int a, int *b, long c, char *d){
  109. 00401000 55 push ebp
  110. 00401001 8B EC mov ebp,esp
  111. printf("", a, b, c, d);
  112. 00401003 8B 45 14 mov eax,dword ptr [ebp+14h]
  113. 00401006 8B 4D 10 mov ecx,dword ptr [ebp+10h]
  114. 00401009 8B 55 0C mov edx,dword ptr [ebp+0Ch]
  115. 0040100C 50 push eax
  116. 0040100D 8B 45 08 mov eax,dword ptr [h]
  117. 00401010 51 push ecx
  118. 00401011 52 push edx
  119. 00401012 50 push eax
  120. 00401013 68 F8 20 40 00 push offset string "" (4020F8h)
  121. 00401018 FF 15 A4 20 40 00 call dword ptr [__imp__printf (4020A4h)]
  122. 0040101E 83 C4 14 add esp,14h
  123. }
  124. 00401021 5D pop ebp
  125. 00401022 C2 10 00 ret 10h
  126.  
  127.  
  128. //foo1呼び出し
  129. foo1(h);
  130. 004011D0 8B 0D 18 30 40 00 mov ecx,dword ptr [h (403018h)]
  131. 004011D6 8B 15 1C 30 40 00 mov edx,dword ptr [h+4 (40301Ch)]
  132. 004011DC 83 EC 10 sub esp,10h
  133. 004011DF 8B C4 mov eax,esp
  134. 004011E1 89 08 mov dword ptr [eax],ecx
  135. 004011E3 8B 0D 20 30 40 00 mov ecx,dword ptr [h+8 (403020h)]
  136. 004011E9 89 50 04 mov dword ptr [eax+4],edx
  137. 004011EC 8B 15 24 30 40 00 mov edx,dword ptr [h+0Ch (403024h)]
  138. 004011F2 89 48 08 mov dword ptr [eax+8],ecx
  139. 004011F5 89 50 0C mov dword ptr [eax+0Ch],edx
  140. 004011F8 E8 03 FE FF FF call foo1 (401000h)
  141.  
  142.  
  143. //foo2呼び出し
  144. foo2(h.a, h.b, h.c, h.d);
  145. 00401200 A1 24 30 40 00 mov eax,dword ptr [h+0Ch (403024h)]
  146. 00401205 8B 0D 20 30 40 00 mov ecx,dword ptr [h+8 (403020h)]
  147. 0040120B 8B 15 1C 30 40 00 mov edx,dword ptr [h+4 (40301Ch)]
  148. 00401211 50 push eax
  149. 00401212 A1 18 30 40 00 mov eax,dword ptr [h (403018h)]
  150. 00401217 51 push ecx
  151. 00401218 52 push edx
  152. 00401219 50 push eax
  153. 0040121A E8 E1 FD FF FF call foo1 (401000h)
  154.  
  155.  
  156. printf: 1.1886e-007
  157. foo1: 1.20982e-007
  158. foo2: 1.21645e-007
  159.  
  160. movで引数を入れるfoo1呼び出しの方が速い。
  161.  
  162.  
  163. ---------------------------------------------------------------------------
  164. Releaseビルド
  165. //((FOO1)foo2)(h); //これがないとfoo2がfoo1に統合されない
  166.  
  167.  
  168. //統合されないfoo1
  169. __declspec(noinline)
  170. void __stdcall foo1(FOO h){
  171. 00401000 55 push ebp
  172. 00401001 8B EC mov ebp,esp
  173. printf("", h.a, h.b, h.c, h.d);
  174. 00401003 8B 45 14 mov eax,dword ptr [ebp+14h]
  175. 00401006 8B 4D 10 mov ecx,dword ptr [ebp+10h]
  176. 00401009 8B 55 0C mov edx,dword ptr [ebp+0Ch]
  177. 0040100C 50 push eax
  178. 0040100D 8B 45 08 mov eax,dword ptr [h]
  179. 00401010 51 push ecx
  180. 00401011 52 push edx
  181. 00401012 50 push eax
  182. 00401013 68 F8 20 40 00 push offset string "" (4020F8h)
  183. 00401018 FF 15 A4 20 40 00 call dword ptr [__imp__printf (4020A4h)]
  184. 0040101E 83 C4 14 add esp,14h
  185. }
  186. 00401021 5D pop ebp
  187. 00401022 C2 10 00 ret 10h
  188.  
  189.  
  190. //統合されないfoo2
  191. __declspec(noinline)
  192. void __stdcall foo2(int a, int *b, long c, char *d){
  193. 00401030 55 push ebp
  194. 00401031 8B EC mov ebp,esp
  195. printf("", a, b, c, d);
  196. 00401033 50 push eax
  197. 00401034 8B 45 08 mov eax,dword ptr [a]
  198. 00401037 51 push ecx
  199. 00401038 52 push edx
  200. 00401039 50 push eax
  201. 0040103A 68 F8 20 40 00 push offset string "" (4020F8h)
  202. 0040103F FF 15 A4 20 40 00 call dword ptr [__imp__printf (4020A4h)]
  203. 00401045 83 C4 14 add esp,14h
  204. }
  205. 00401048 5D pop ebp
  206. 00401049 C2 04 00 ret 4
  207.  
  208.  
  209. //foo1呼び出し
  210. foo1(h);
  211. 004011F0 8B 0D 18 30 40 00 mov ecx,dword ptr [h (403018h)]
  212. 004011F6 8B 15 1C 30 40 00 mov edx,dword ptr [h+4 (40301Ch)]
  213. 004011FC 83 EC 10 sub esp,10h
  214. 004011FF 8B C4 mov eax,esp
  215. 00401201 89 08 mov dword ptr [eax],ecx
  216. 00401203 8B 0D 20 30 40 00 mov ecx,dword ptr [h+8 (403020h)]
  217. 00401209 89 50 04 mov dword ptr [eax+4],edx
  218. 0040120C 8B 15 24 30 40 00 mov edx,dword ptr [h+0Ch (403024h)]
  219. 00401212 89 48 08 mov dword ptr [eax+8],ecx
  220. 00401215 89 50 0C mov dword ptr [eax+0Ch],edx
  221. 00401218 E8 E3 FD FF FF call foo1 (401000h)
  222.  
  223.  
  224. //foo2呼び出し
  225. foo2(h.a, h.b, h.c, h.d);
  226. 00401220 A1 18 30 40 00 mov eax,dword ptr [h (403018h)]
  227. 00401225 8B 0D 20 30 40 00 mov ecx,dword ptr [h+8 (403020h)]
  228. 0040122B 8B 15 1C 30 40 00 mov edx,dword ptr [h+4 (40301Ch)]
  229. 00401231 50 push eax
  230. 00401232 A1 24 30 40 00 mov eax,dword ptr [h+0Ch (403024h)]
  231. 00401237 E8 F4 FD FF FF call foo2 (401030h)
  232.  
  233.  
  234. printf: 1.1888e-007
  235. foo1: 1.21176e-007
  236. foo2: 1.13223e-007
  237.  
  238. foo1とfoo2は関数自体が違うので、呼び出し方のベンチにならない。
  239. 関数自体はfoo2の方が速い。なぜかprintfよりも速い。
  240.  
  241.  
  242. ---------------------------------------------------------------------------
  243. Debugビルド
  244.  
  245. printf: 1.94619e-007
  246. foo1: 2.12508e-007
  247. foo2: 2.10874e-007
  248.  
  249. foo1とfoo2は関数自体が違うので、呼び出し方のベンチにならない。
  250.  
  251. */
  252.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty