ちょっとした疑問は自分で解決しましょう

 ふと思ったこと。

「num += 2」とかより「num++;num++;」とかの方が速かったりしないのかな

インクリメントは全命令の中でもトップクラスのスピードらしいし。



 というわけで、検証してみた。

コードは最後に書くとして(長めだし)、

結果は…、

  • > loop x 16777215

num ++ x2 : 98723μs
num += 2 : 45540μs

こんな感じ*1

 ちなみに、Debugでやりました。

Releaseだと最適化かけたせいか一瞬で終わってしまって、

両方とも0μsになってしまうので(汗)



 結果は…、結局「+=」の方が速いと。



 ……?でも、このコードは変なんじゃないかね?(汗)


(アセンブラのコードから抜粋)
; 39 : num ++;

000be 8b 45 ac mov eax, DWORD PTR _num$[ebp]
000c1 83 c0 01 add eax, 1
000c4 89 45 ac mov DWORD PTR _num$[ebp], eax

……何でinc命令使ってないんでしょう??





 で、以下今回のコードです


#include "windows.h"
#include "stdio.h"

#pragma comment( lib, "winmm.lib" )


#define LOOP_TIMES 0x00ffffff


int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst,
LPSTR lpCmdLine, int nCmdShow )
{
FILE *fp = fopen( "Test.txt", "wt" );
//DWORD time = 0;
LARGE_INTEGER time[2], freq;
DWORD d_time = 0;

DWORD i = 0;
int num = 0;

if( fp == NULL )
{
return -1;
}

fprintf( fp, "->\tloop x %d\n\n", LOOP_TIMES );

timeBeginPeriod( 1 );

// num ++
//time = timeGetTime();

QueryPerformanceFrequency( &freq );
QueryPerformanceCounter( &(time[0]) );

for( i=0 ; i// 上記のアセンブラはここの行
num ++;
}
//time = timeGetTime() -time;
QueryPerformanceCounter( &(time[1]) );
d_time = (DWORD)((time[1].QuadPart-time[0].QuadPart) * 1000000 / freq.QuadPart);


fprintf( fp, "num ++ x2\t: %dμs\n", d_time );

num = 0;
// num += 2
//time = timeGetTime();

QueryPerformanceFrequency( &freq );
QueryPerformanceCounter( &(time[0]) );

for( i=0 ; i//time = timeGetTime() -time;
QueryPerformanceCounter( &(time[1]) );
d_time = (DWORD)((time[1].QuadPart-time[0].QuadPart) * 1000000 / freq.QuadPart);

fprintf( fp, "num += 2\t: %dμs\n", d_time );

timeEndPeriod( 1 );

fclose( fp );

return 0;
}

 いちいちWindowsでやっているのは、

「timeGetTime()」とか「QueryPerformanceCounter()」あたりで

手軽に時間を取りたかったからです。




*1:「loop x n」は試行回数。
今回は0x00ffffff回やってみました。
(0xffffffffだとちょいと長すぎたので1バイト削ってみた)