UWSCのループ速度と時間取得精度について
UWSCのループは三種類。
同じ回数のループでどれだけ早さが違うかと、時刻取得APIの精度を検証してみた。
修正 2015/06/11
時刻取得に1msec精度が必要ならAPIコールをすること。ただしGETTIMEの方が早い。
手元の環境では
- ループは、Forが最も早い
- 時刻取得はGETTIMEが推奨(15msec程度の精度)だが、1msec精度が欲しいならAPIコールすべし
検証に使ったスクリプト
OPTION EXPLICIT // timeGetTimeは1ms、GetTickCountは5msの精度らしいですが、、、 DEF_DLL timeGetTime(): LONG: winmm DEF_DLL timeBeginPeriod(DWORD): LONG: winmm DEF_DLL timeEndPeriod(DWORD): LONG: winmm DEF_DLL GetTickCount(): LONG: kernel32 PUBLIC num[10000], i, m = LENGTH(num) PRINT timeBeginPeriod(1) SLEEP(0.5) // timeBeginPeriodを反映するのに少し時間が必要。多分500msecもいらいないけど PRINT "<#CR>timeGetTime" FOR i = 0 TO m - 1 num[i] = timeGetTime() NEXT PrintResult() PRINT timeEndPeriod(1) // 1msecの変化が拾える。100ループ前後で値が変わる。1万ループで103〜105msec PRINT "<#CR>GetTickCount" FOR i = 0 TO m - 1 num[i] = GetTickCount() NEXT PrintResult() // 15ないし16msecの変化しか拾えない。1500ループ前後で値が変わる。1万ループで94〜109msec PRINT "<#CR>GetTime" FOR i = 0 TO m - 1 num[i] = GetTime() * 1000 + G_TIME_ZZ NEXT PrintResult() // 15ないし16msecの変化しか拾えない。1750ループ前後で値が変わる。1万ループで78〜94msec PRINT "<#CR>While" i = 0 WHILE i < m num[i] = GetTime() * 1000 + G_TIME_ZZ i = i + 1 WEND PrintResult() // 1200ループ弱で値が変わる。1万ループで125〜141msec PRINT "<#CR>Repeat" i = 0 REPEAT num[i] = GetTime() * 1000 + G_TIME_ZZ i = i + 1 UNTIL i >= m PrintResult() // 1200ループ弱で値が変わる。1万ループで125〜140msec PRINT "<#CR>Recursive" Recursive(700) PrintResult() // 1000も再帰はできない(落ちる) PROCEDURE PrintResult() PRINT "0 " + num[0] FOR i = 1 TO m - 1 IF num[i] <> num[i - 1] THEN PRINT i + " " + num[i] NEXT PRINT "res " + (num[m - 1] - num[0]) FEND PROCEDURE Recursive(n) num[n] = GetTime() * 1000 + G_TIME_ZZ IF n > 0 THEN Recursive(n - 1) FEND
単純に全力ループして、num配列にミリ秒単位の値を入れるだけ。
PrintResultは、値の変わった時と末尾-先頭を出すので、
たくさんPrintされる方が、時刻取得精度が良く、差分が小さい方がループが早い。
再帰は都合により逆順なのと、末尾が未取得なので、差分はあてにならない。