プチコン3号で色々実験/速度編

  • tags
    • petitcom
  • last modified2015-01-29
  • created2015-01-10

はじめに

プチコン3号でどの命令が速いかをとりあえず測ってみたメモ. 大体New3DS+実験時の最新バージョンで実行している.

速度を調べるときは下記のような方法用いているが省略している. 値はそこそこばらつくため,あまり正確では無い. 結果については(だいたい)コメント部分に記述した.

OPTION DEFINT
WAIT:T=MAINCNT
'測定する処理
?MAINCNT-T

整数/算術演算子

SMILEBASIC ver 3.0.2 / New3DS

A%=1:FOR I=1 TO 2000000:B%=A%+1:NEXT     ' 155
A%=1:FOR I=1 TO 2000000:B%=A%-1:NEXT     ' 157
A%=1:FOR I=1 TO 2000000:B%=A%*1:NEXT     ' 167
A%=1:FOR I=1 TO 2000000:B%=A%/1:NEXT     ' 170
A%=1:FOR I=1 TO 2000000:B%=A% MOD 1:NEXT ' 168
A%=1:FOR I=1 TO 2000000:B%=A% DIV 1:NEXT ' 165

/よりもDIVがちょっと速いらしい.

整数/比較演算子

SMILEBASIC ver 3.0.2 / New3DS

A%=1:FOR I=1 TO 2000000:B%=A%>1:NEXT  ' 181
A%=1:FOR I=1 TO 2000000:B%=A%<1:NEXT  ' 168
A%=1:FOR I=1 TO 2000000:B%=A%>=1:NEXT ' 168
A%=1:FOR I=1 TO 2000000:B%=A%<=1:NEXT ' 164
A%=1:FOR I=1 TO 2000000:B%=A%==1:NEXT ' 171
A%=1:FOR I=1 TO 2000000:B%=A%!=1:NEXT ' 168

大体割り算くらい遅い.<=が最速.

整数/ビット演算子

SMILEBASIC ver 3.0.2 / New3DS

A%=1:FOR I=1 TO 2000000:B%=A% AND 1:NEXT ' 161
A%=1:FOR I=1 TO 2000000:B%=A% OR 1:NEXT  ' 160
A%=1:FOR I=1 TO 2000000:B%=A% XOR 1:NEXT ' 165
A%=1:FOR I=1 TO 2000000:B%=NOT A%:NEXT   ' 159
A%=1:FOR I=1 TO 2000000:B%=A% << 1:NEXT  ' 165
A%=1:FOR I=1 TO 2000000:B%=A% >> 1:NEXT  ' 167

XORとシフトがちょっと遅い.

整数/論理演算子

SMILEBASIC ver 3.0.2 / New3DS

A%=1:FOR I=1 TO 2000000:B%=A% && 1:NEXT ' 205
A%=1:FOR I=1 TO 2000000:B%=A% || 1:NEXT ' 185
A%=1:FOR I=1 TO 2000000:B%=!A%:NEXT     ' 153

遅い.一旦boolに変換して処理だからか.

実数/算術演算子

SMILEBASIC ver 3.0.2 / New3DS

A#=1:FOR I=1 TO 2000000:B#=A#+1:NEXT     ' 157
A#=1:FOR I=1 TO 2000000:B#=A#-1:NEXT     ' 162
A#=1:FOR I=1 TO 2000000:B#=A#*1:NEXT     ' 180
A#=1:FOR I=1 TO 2000000:B#=A#/1:NEXT     ' 163
A#=1:FOR I=1 TO 2000000:B#=A# MOD 1:NEXT ' 179
A#=1:FOR I=1 TO 2000000:B#=A# DIV 1:NEXT ' 175

除算は速くなる.DIVにすると逆効果.乗算が結構遅い.

実数/比較演算子

SMILEBASIC ver 3.0.2 / New3DS

A#=1:FOR I=1 TO 2000000:B#=A#>1:NEXT  ' 189
A#=1:FOR I=1 TO 2000000:B#=A#<1:NEXT  ' 174
A#=1:FOR I=1 TO 2000000:B#=A#>=1:NEXT ' 177
A#=1:FOR I=1 TO 2000000:B#=A#<=1:NEXT ' 173
A#=1:FOR I=1 TO 2000000:B#=A#==1:NEXT ' 178
A#=1:FOR I=1 TO 2000000:B#=A#!=1:NEXT ' 174

やはり<=がちょっと速い.実数でも>が一番遅い.

実数/ビット演算子

SMILEBASIC ver 3.0.2 / New3DS

A#=1:FOR I=1 TO 2000000:B#=A# AND 1:NEXT ' 168
A#=1:FOR I=1 TO 2000000:B#=A# OR 1:NEXT  ' 167
A#=1:FOR I=1 TO 2000000:B#=A# XOR 1:NEXT ' 171
A#=1:FOR I=1 TO 2000000:B#=NOT A#:NEXT   ' 164
A#=1:FOR I=1 TO 2000000:B#=A# << 1:NEXT  ' 175
A#=1:FOR I=1 TO 2000000:B#=A# >> 1:NEXT  ' 170

実数/論理演算子

SMILEBASIC ver 3.0.2 / New3DS

A#=1:FOR I=1 TO 2000000:B#=A# && 1:NEXT ' 211
A#=1:FOR I=1 TO 2000000:B#=A# || 1:NEXT ' 189
A#=1:FOR I=1 TO 2000000:B#=!A#:NEXT     ' 157

サブルーチンと関数呼び出し

SMILEBASIC ver 3.0.2 / New3DS

@NOP:RETURN
DEF NOP:END
FOR I=1 TO 2000000:GOSUB @NOP:NEXT         ' 147
A$="@NOP":FOR I=1 TO 2000000:GOSUB A$:NEXT ' 233
FOR I=1 TO 2000000:NOP:NEXT                ' 488
A$="NOP":FOR I=1 TO 2000000:CALL A$:NEXT   ' 578

サブルーチンが速いのは当然だけど,結構差が大きい. 関数内でサブルーチン使えないのがやはり不便だな.

ループ

SMILEBASIC ver 3.0.2 / New3DS

FOR I=1 TO 2000000:NEXT               ' 118
I=0:WHILE I!=2000000:INC I:WEND       ' 97
I=0:REPEAT:INC I:UNTIL I==2000000     ' 90
I=0:@A:INC I:IF I<=2000000 GOTO @A    ' 98
I=0:@B:INC I:ON I<=2000000 GOTO @C,@B ' 108

REPEAT最速.

GCLSとGFILL

SMILEBASIC ver 3.0.2 / New3DS

FOR I=1 TO 10000:GCLS:NEXT                ' 493
FOR I=1 TO 10000:GFILL 0,0,399,239,0:NEXT ' 193

クリア範囲が違うので当然の結果. 横着せずに必要な範囲だけクリアした方が速いという当たり前の話.

INC/DEC

SMILEBASIC ver 3.0.2 / New3DS

A%=0:FOR I=1 TO 2000000:INC A%:NEXT  ' 155
A%=0:FOR I=1 TO 2000000:A%=A%+1:NEXT ' 155
A%=0:FOR I=1 TO 2000000:DEC A%:NEXT  ' 158
A%=0:FOR I=1 TO 2000000:A%=A%-1:NEXT ' 157

差は無い.

INC A[FUNC()] でFUNCが2度実行されるという報告があるようなので,実際A=A+1に変換されているのかも.

GLINE

SMILEBASIC ver 3.0.2 / New3DS

FOR I=1 TO 200000:GLINE 0,0,200,0:NEXT   ' 69
FOR I=1 TO 200000:GLINE 0,0,0,200:NEXT   ' 65
FOR I=1 TO 200000:GLINE 0,0,200,200:NEXT ' 165

多分,垂直/水平な場合は特別扱い. なぜか縦の方が地味に速い.