各種リフレインのプログラム 6 種のベンチマークをとってみました。
コードを見ればだいたい分かると思いますがそれぞれの説明。
それぞれ、 n が 0 以下の場合の処理は消してあります。
#include "kernel32.as"
#module
#deffunc refrain_a str text, int n, var dest
sdim dest, strlen( text ) * n + 1
repeat n
dest += text
loop
return
#deffunc refrain_b str text, int n, var dest, local index
sdim dest, strlen( text ) * n + 1
index = 0
repeat n
poke dest, index, text
index += strsize
loop
return
#deffunc refrain_c str text, int n, var dest, local _dest
sdim dest, strlen( text ) * n + 1
if( n == 1 ) : dest = text : return
refrain_c text + text, n / 2, _dest
dest = _dest
if( n & 1 ) : dest += text
return
#deffunc refrain_d str _text, int _n, var dest, local text, local n, local textindex, local destindex, local size
n = _n
size = strlen( _text ) * n + 1
sdim text, size
poke text, 0, _text
textindex = strsize
sdim dest, size
destindex = 0
repeat
if( n & 1 ) {
poke dest, destindex, text
destindex += strsize
}
if( n == 1 ) : break
poke text, textindex, text
textindex += strsize
n /= 2
loop
return
#deffunc refrain_e str _text, int n, var dest, local text, local len, local bufWidth, local osel, local vram
text = _text
len = strlen( text )
bufWidth = len * n
osel = ginfo_sel
buffer 29, bufWidth, 1, 1
mref vram, 66
memcpy vram, text, len
gmode 1, bufWidth - len, 1
pos len, 0
gcopy ginfo_sel
sdim dest, bufWidth + 1
memcpy dest, vram, bufWidth
gsel osel
return
#deffunc refrain_f str _text, int n, var dest, local text, local len, local prm, local dummy
if( code == 0 ) {
code = $0c244c8b, $177ec985, $0424448b, $24748b56, $88108a0c, $c0833014, $01e98301, $c25ef375, $0000000c
VirtualProtect varptr( code ), length(code)*4, $40, varptr( dummy )
}
text = _text
len = strlen( text )
sdim dest, len * n + 1
dest = text
prm = varptr( dest ), len, len * ( n - 1 )
dummy = callfunc( prm, varptr( code ), 3 )
return
#deffunc refrain int kind, str text, int n, var dest
if( kind == 0 ) {
refrain_a text, n, dest
} else : if( kind == 1 ) {
refrain_b text, n, dest
} else : if( kind == 2 ) {
refrain_c text, n, dest
} else : if( kind == 3 ) {
refrain_d text, n, dest
} else : if( kind == 4 ) {
refrain_e text, n, dest
} else : if( kind == 5 ) {
refrain_f text, n, dest
}
return
#global
#include "d3m.hsp"
mes "計測開始"
repeat 6
kind = cnt
startTime = d3timer()
repeat 100
refrain kind, "repeat after me ", 1024, dest
loop
endTime = d3timer()
mes strf("%c : ", 'A' + kind ) + strf( "%.2f ms", double( endTime - startTime ) / 100 )
loop
mes "計測終了"
私の PC ( Windows XP Home SP2 / Pentium 4 CPU 2.40GHz / 512 MB RAM )での結果。