作成者 |
メッセージ |
|
|
こんにちは。
やってみると中々勉強になりました。
トモカズさんのプログラムのしたいことに沿えているか疑問なのですが
書いてみました。
1、計算の基の数値は3まで
2、多次元配列だけど、計算で使うのは1本
3、各項に3の3倍数を順次掛けて足す
に注目だけしてみました。
でも、これがFunctionを使うと途端に遅くなるんですね・・・
FORの中に同じ式をほり込んでやるとぐっと早くなるのに。
計算コストとか処理のコストとかはさっぱり分からないですが
私の方ではこんなのを書いてみました。
下記ではFunctionは書いてありますが使っていません。
コード:
#N88BASIC
Dim d as BytePtr
Dim P%[9,9,59] AS Integer
Dim R%[9,9,59] AS Byte
Dim TA AS DWord
Dim X AS Char
Dim Y AS Char
Dim dwStart AS int64
Dim dwEnd AS int64
Dim TIMECOUNT AS int64
Dim CT AS Int64
Dim CT2 AS Int64
Dim N AS Char
N=1
Randomize
d=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,9)
FOR X=1 TO 8
FOR Y=1 TO 8
P%(X,Y,N)=Int(Rnd()*3)
R%(X,Y,N)=P%(X,Y,N) AS Char
NEXT
'使用する数値は3以下→1バイトでOKと思われる
d[X-1]=P%(1,X,N) '場所をずらして頂戴します。
NEXT
PRINT "計算スピードテスト"
CT2=20000000
Print "Byte"
dwStart = GetTickCount()
FOR CT=0 TO CT2
'TA=TA + TEST_byte(d)
TA=TA +d[0]+d[1]*3+d[2]*9+d[3]*27+d[4]*81+d[5]*243_
+d[6]*729+d[7]*2187
NEXT
PRINT TA
GOSUB *TIMEPRINT
Sleep(-1)
END
*TIMEPRINT
dwEnd = GetTickCount()
TIMECOUNT=(dwEnd-dwStart)/100
PRINT TIMECOUNT/10;"秒"
RETURN
Function TEST_byte(a as BytePtr) as Integer
TEST_byte=a[0]+a[1]*3+a[2]*9+a[3]*27+a[4]*81+a[5]*243_
+a[6]*729+a[7]*2187
end Function
[/code]
こんにちは。 やってみると中々勉強になりました。 トモカズさんのプログラムのしたいことに沿えているか疑問なのですが 書いてみました。 1、計算の基の数値は3まで 2、多次元配列だけど、計算で使うのは1本 3、各項に3の3倍数を順次掛けて足す に注目だけしてみました。 でも、これがFunctionを使うと途端に遅くなるんですね・・・ FORの中に同じ式をほり込んでやるとぐっと早くなるのに。 計算コストとか処理のコストとかはさっぱり分からないですが 私の方ではこんなのを書いてみました。 下記ではFunctionは書いてありますが使っていません。
[code] #N88BASIC
Dim d as BytePtr
Dim P%[9,9,59] AS Integer Dim R%[9,9,59] AS Byte Dim TA AS DWord Dim X AS Char Dim Y AS Char Dim dwStart AS int64 Dim dwEnd AS int64 Dim TIMECOUNT AS int64 Dim CT AS Int64 Dim CT2 AS Int64 Dim N AS Char
N=1
Randomize
d=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,9)
FOR X=1 TO 8 FOR Y=1 TO 8 P%(X,Y,N)=Int(Rnd()*3) R%(X,Y,N)=P%(X,Y,N) AS Char NEXT '使用する数値は3以下→1バイトでOKと思われる d[X-1]=P%(1,X,N) '場所をずらして頂戴します。 NEXT
PRINT "計算スピードテスト" CT2=20000000
Print "Byte" dwStart = GetTickCount() FOR CT=0 TO CT2 'TA=TA + TEST_byte(d) TA=TA +d[0]+d[1]*3+d[2]*9+d[3]*27+d[4]*81+d[5]*243_ +d[6]*729+d[7]*2187 NEXT PRINT TA GOSUB *TIMEPRINT Sleep(-1)
END
*TIMEPRINT dwEnd = GetTickCount() TIMECOUNT=(dwEnd-dwStart)/100 PRINT TIMECOUNT/10;"秒" RETURN
Function TEST_byte(a as BytePtr) as Integer
TEST_byte=a[0]+a[1]*3+a[2]*9+a[3]*27+a[4]*81+a[5]*243_ +a[6]*729+a[7]*2187
end Function [/code][/code]
|
|
|
投稿記事 |
Posted: 2010年5月10日(月) 18:14 |
|
|
|
|
|
koboさん、返信ありがとうございます。
>実験的な事を繰り返して
ご推察の通りです。様々なアイデアを試しつつ試行錯誤を繰り返しています。
それらのアイデアのほとんどがボツになったりしておりますが・・
そんな訳で今回の(処理速度向上の)質問も的外れだったかもしれませんね。
>まず第一に多次元配列ではない方法でも実験をされてはいかがでしょうか。
そうですね。それも検討してみましたがまだ実験するに至っておりませんでした。
結構、X座標 Y座標を使用して配列を参照するケースが多いので、
P%(X,Y) を P%(X*8+Y) とした場合、X*8に処理コストがかかってしまうのでは無いかと却下しておりました。※今回のケースでは*8です。これだと機械語もビットシフトしてくれていればコストはさほど無さそうな気がしてきました。
これも、簡単なサンプルでベンチマークしてみる必要がありそうですね。
>HeapAllocでメモリを確保して、どこに書き込むかは人間側で計算し管理して
>書き込んでいきます。
ちょっと勉強してみます。
>また、数式を出来るだけ計算しておいてあげるのも一つだと思います。
>(x*2)*(x*3)のような式であれば、これを展開しておいたほうが速いかもしれません。
以下のコードを書いてみました。
*TEST01-04のサブルーチンがソレです。予め計算結果を配列に代入しておき、それを参照して累計だけを行うというものです。※今回のケースでは配列に入力されている数値は0~2だけなので・・・
残念ながらこれだと(計算をするよりも)配列を読みに行く時間の方がかかってしまっていました。
(koboさんの書かれている内容と異なった解釈をしているのかもしれません)
中々と難しいものです。
次回は1次元配列を試してみようかと思っております。ご丁寧な解説をありがとうございました。
コード:
#N88BASIC
Dim P%[9,9,59] AS Integer
Dim R%[9,9,59] AS Char
Dim Q%[59,9,9] AS Integer '追加
Dim TA1% AS Integer
Dim X AS Char
Dim Y AS Char
Dim I$ AS STRING
Dim dwStart AS int64
Dim dwEnd AS int64
Dim TIMECOUNT AS int64
Dim CT AS Int64
Dim CT2 AS Int64
Dim N AS Char
dim CV1[2] AS Integer '追加
dim CV2[2] AS Integer '追加
dim CV3[2] AS Integer '追加
dim CV4[2] AS Integer '追加
dim CV5[2] AS Integer '追加
dim CV6[2] AS Integer '追加
dim CV7[2] AS Integer '追加
dim CV8[2] AS Integer '追加
'予め計算しておく '追加
FOR N=0 TO 2
CV1[N]=N
CV2[N]=N*3
CV3[N]=N*3^2
CV4[N]=N*3^3
CV5[N]=N*3^4
CV6[N]=N*3^5
CV7[N]=N*3^6
CV8[N]=N*3^7
NEXT
N=1
Randomize
FOR X=1 TO 8
FOR Y=1 TO 8
P%[X,Y,N]=Int(Rnd()*3)
Q%[N,X,Y]=P%[X,Y,N]
R%[X,Y,N]=P%[X,Y,N] AS Char
NEXT
NEXT
PRINT "計算スピードテスト"
CT2=20000000
Print
Gosub *TEST01-00:PRINT TA1%
Gosub *TEST01-01:PRINT TA1% '追加
Gosub *TEST01-02:PRINT TA1%
Gosub *TEST01-03:PRINT TA1% '追加
Gosub *TEST01-04:PRINT TA1% '追加
Print "Integer(通常)"
dwStart = GetTickCount()
FOR CT=0 TO CT2:GOSUB *TEST01-00:NEXT
PRINT TA1%
GOSUB *TIMEPRINT
PRINT
Print "Integer(通常) 配列順序を入れ替え"
dwStart = GetTickCount()
FOR CT=0 TO CT2:GOSUB *TEST01-01:NEXT
PRINT TA1%
GOSUB *TIMEPRINT
PRINT
Print "Char(Integerへ全部変換しながら計算)"
dwStart = GetTickCount()
FOR CT=0 TO CT2:GOSUB *TEST01-02:NEXT
PRINT TA1%
GOSUB *TIMEPRINT
PRINT
Print "Char(Integerへ一部変換しながら計算)"
dwStart = GetTickCount()
FOR CT=0 TO CT2:GOSUB *TEST01-03:NEXT
PRINT TA1%
GOSUB *TIMEPRINT
PRINT
Print "Char(Integerへ配列を参照して累計のみ 掛算なし)"
dwStart = GetTickCount()
FOR CT=0 TO CT2:GOSUB *TEST01-04:NEXT
PRINT TA1%
GOSUB *TIMEPRINT
PRINT
I$=Input$(1)
END
*TIMEPRINT
dwEnd = GetTickCount()
TIMECOUNT=(dwEnd-dwStart)/100
PRINT TIMECOUNT/10;"秒"
RETURN
*TEST01-00
TA1%=P%[1,1,N]+P%[1,2,N]*3+P%[1,3,N]*9+P%[1,4,N]*27+P%[1,5,N]*81+P%[1,6,N]*243+P%[1,7,N]*729+P%[1,8,N]*2187
RETURN
*TEST01-01
TA1%=Q%[N,1,1]+Q%[N,1,2]*3+Q%[N,1,3]*9+Q%[N,1,4]*27+Q%[N,1,5]*81+Q%[N,1,6]*243+Q%[N,1,7]*729+Q%[N,1,8]*2187
RETURN
*TEST01-02
TA1%=R%[1,1,N] AS Integer+R%[1,2,N] AS Integer*3+R%[1,3,N] AS Integer*9+R%[1,4,N] AS Integer*27+R%[1,5,N] AS Integer*81+R%[1,6,N] AS Integer*243+R%[1,7,N] AS Integer*729+R%[1,8,N] AS Integer*2187
RETURN
*TEST01-03
TA1%=(R%[1,1,N]+R%[1,2,N]*3+R%[1,3,N]*9+R%[1,4,N]*27) AS Integer +R%[1,5,N] AS Integer*81 +R%[1,6,N] AS Integer*243+R%[1,7,N] AS Integer*729+R%[1,8,N] AS Integer*2187
RETURN
*TEST01-04
TA1%=CV1[R%(1,1,N)]+CV2[R%(1,2,N)]+CV3[R%(1,3,N)]+CV4[R%(1,4,N)]+CV5[R%(1,5,N)]+CV6[R%(1,6,N)]+CV7[R%(1,7,N)]+CV8[R%(1,8,N)]
RETURN
koboさん、返信ありがとうございます。
>実験的な事を繰り返して
ご推察の通りです。様々なアイデアを試しつつ試行錯誤を繰り返しています。 それらのアイデアのほとんどがボツになったりしておりますが・・ そんな訳で今回の(処理速度向上の)質問も的外れだったかもしれませんね。
>まず第一に多次元配列ではない方法でも実験をされてはいかがでしょうか。
そうですね。それも検討してみましたがまだ実験するに至っておりませんでした。 結構、X座標 Y座標を使用して配列を参照するケースが多いので、 P%(X,Y) を P%(X*8+Y) とした場合、X*8に処理コストがかかってしまうのでは無いかと却下しておりました。※今回のケースでは*8です。これだと機械語もビットシフトしてくれていればコストはさほど無さそうな気がしてきました。 これも、簡単なサンプルでベンチマークしてみる必要がありそうですね。
>HeapAllocでメモリを確保して、どこに書き込むかは人間側で計算し管理して >書き込んでいきます。
ちょっと勉強してみます。
>また、数式を出来るだけ計算しておいてあげるのも一つだと思います。 >(x*2)*(x*3)のような式であれば、これを展開しておいたほうが速いかもしれません。
以下のコードを書いてみました。
*TEST01-04のサブルーチンがソレです。予め計算結果を配列に代入しておき、それを参照して累計だけを行うというものです。※今回のケースでは配列に入力されている数値は0~2だけなので・・・ 残念ながらこれだと(計算をするよりも)配列を読みに行く時間の方がかかってしまっていました。 (koboさんの書かれている内容と異なった解釈をしているのかもしれません)
中々と難しいものです。 次回は1次元配列を試してみようかと思っております。ご丁寧な解説をありがとうございました。
[code] #N88BASIC
Dim P%[9,9,59] AS Integer Dim R%[9,9,59] AS Char Dim Q%[59,9,9] AS Integer '追加 Dim TA1% AS Integer Dim X AS Char Dim Y AS Char Dim I$ AS STRING Dim dwStart AS int64 Dim dwEnd AS int64 Dim TIMECOUNT AS int64 Dim CT AS Int64 Dim CT2 AS Int64 Dim N AS Char dim CV1[2] AS Integer '追加 dim CV2[2] AS Integer '追加 dim CV3[2] AS Integer '追加 dim CV4[2] AS Integer '追加 dim CV5[2] AS Integer '追加 dim CV6[2] AS Integer '追加 dim CV7[2] AS Integer '追加 dim CV8[2] AS Integer '追加
'予め計算しておく '追加 FOR N=0 TO 2 CV1[N]=N CV2[N]=N*3 CV3[N]=N*3^2 CV4[N]=N*3^3 CV5[N]=N*3^4 CV6[N]=N*3^5 CV7[N]=N*3^6 CV8[N]=N*3^7 NEXT
N=1 Randomize
FOR X=1 TO 8 FOR Y=1 TO 8 P%[X,Y,N]=Int(Rnd()*3) Q%[N,X,Y]=P%[X,Y,N] R%[X,Y,N]=P%[X,Y,N] AS Char NEXT NEXT
PRINT "計算スピードテスト" CT2=20000000
Print Gosub *TEST01-00:PRINT TA1% Gosub *TEST01-01:PRINT TA1% '追加 Gosub *TEST01-02:PRINT TA1% Gosub *TEST01-03:PRINT TA1% '追加 Gosub *TEST01-04:PRINT TA1% '追加
Print "Integer(通常)" dwStart = GetTickCount() FOR CT=0 TO CT2:GOSUB *TEST01-00:NEXT PRINT TA1% GOSUB *TIMEPRINT PRINT
Print "Integer(通常) 配列順序を入れ替え" dwStart = GetTickCount() FOR CT=0 TO CT2:GOSUB *TEST01-01:NEXT PRINT TA1% GOSUB *TIMEPRINT PRINT
Print "Char(Integerへ全部変換しながら計算)" dwStart = GetTickCount() FOR CT=0 TO CT2:GOSUB *TEST01-02:NEXT PRINT TA1% GOSUB *TIMEPRINT PRINT
Print "Char(Integerへ一部変換しながら計算)" dwStart = GetTickCount() FOR CT=0 TO CT2:GOSUB *TEST01-03:NEXT PRINT TA1% GOSUB *TIMEPRINT PRINT
Print "Char(Integerへ配列を参照して累計のみ 掛算なし)" dwStart = GetTickCount() FOR CT=0 TO CT2:GOSUB *TEST01-04:NEXT PRINT TA1% GOSUB *TIMEPRINT PRINT
I$=Input$(1) END
*TIMEPRINT dwEnd = GetTickCount() TIMECOUNT=(dwEnd-dwStart)/100 PRINT TIMECOUNT/10;"秒" RETURN
*TEST01-00 TA1%=P%[1,1,N]+P%[1,2,N]*3+P%[1,3,N]*9+P%[1,4,N]*27+P%[1,5,N]*81+P%[1,6,N]*243+P%[1,7,N]*729+P%[1,8,N]*2187 RETURN
*TEST01-01 TA1%=Q%[N,1,1]+Q%[N,1,2]*3+Q%[N,1,3]*9+Q%[N,1,4]*27+Q%[N,1,5]*81+Q%[N,1,6]*243+Q%[N,1,7]*729+Q%[N,1,8]*2187 RETURN
*TEST01-02 TA1%=R%[1,1,N] AS Integer+R%[1,2,N] AS Integer*3+R%[1,3,N] AS Integer*9+R%[1,4,N] AS Integer*27+R%[1,5,N] AS Integer*81+R%[1,6,N] AS Integer*243+R%[1,7,N] AS Integer*729+R%[1,8,N] AS Integer*2187 RETURN
*TEST01-03 TA1%=(R%[1,1,N]+R%[1,2,N]*3+R%[1,3,N]*9+R%[1,4,N]*27) AS Integer +R%[1,5,N] AS Integer*81 +R%[1,6,N] AS Integer*243+R%[1,7,N] AS Integer*729+R%[1,8,N] AS Integer*2187 RETURN
*TEST01-04 TA1%=CV1[R%(1,1,N)]+CV2[R%(1,2,N)]+CV3[R%(1,3,N)]+CV4[R%(1,4,N)]+CV5[R%(1,5,N)]+CV6[R%(1,6,N)]+CV7[R%(1,7,N)]+CV8[R%(1,8,N)] RETURN [/code]
|
|
|
投稿記事 |
Posted: 2010年5月08日(土) 10:29 |
|
|
|
|
|
>しかし、トモカズさんは大人ですね。。。これからも頑張ってください。
ガキで悪かったですねえ。。。
>私もN88BASICで育った人間で、ABしかほぼ使えません。
僕もN88-BASICで育った人間ですがね。
>色々突っ込みどころが満載な返答ですが、上から目線だとか文盲だとかは
>重々承知しておりますので、苦笑いでスルーされますようお願い申し上げます。
僕に石を投げておいて予防線を張るのはいかがなもんでしょ。
>しかし、トモカズさんは大人ですね。。。これからも頑張ってください。 ガキで悪かったですねえ。。。
>私もN88BASICで育った人間で、ABしかほぼ使えません。 僕もN88-BASICで育った人間ですがね。
>色々突っ込みどころが満載な返答ですが、上から目線だとか文盲だとかは >重々承知しておりますので、苦笑いでスルーされますようお願い申し上げます。 僕に石を投げておいて予防線を張るのはいかがなもんでしょ。
|
|
|
投稿記事 |
Posted: 2010年5月08日(土) 06:47 |
|
|
|
|
|
こんばんは。
おそらく、実験的な事を繰り返して頭を捏ねているのかなと勝手に推察します。
云十年前はじめてパソコンに触れていた頃に同じような事をいっぱいしました。
回答だと決め付けられたプログラムを勉強するのではなく
自ら回答を探すからこそ、発想が思わぬ回答を持ち出して愉快になることが
多々あるかと思います。
しかし、トモカズさんは大人ですね。。。これからも頑張ってください。
さてさて、計算速度を上げたいとの事ですが
多次元配列は、何をするにも遅いと聞いた事があります。
ですので、まず第一に多次元配列ではない方法でも実験をされてはいかがでしょうか。
あと、このプログラムを組み込んで行く先の都合にもよりますが、
式を見ると計算の桁数がとても多くなりますね。ですので
必要な時に必要な部分だけ計算をするのも体感速度を上げてくれます。
また、数式を出来るだけ計算しておいてあげるのも一つだと思います。
(x*2)*(x*3)のような式であれば、これを展開しておいたほうが速いかもしれません。
私が、速度を上げる時はパソコン任せの部分を人間が管理することで
パソコンの負担を減らしてやるってのが良くやる手です。
多次元でも、メモリの並びは一直線上に並んでいるものと考えて良いそうです。
(10,10)の多次元で(0,0)の場所が0番地だとすると
(0,1)は1番地、(0,2)は2番地、(0,9)は9番地となって次の
(1,0)は10番地という感じだそうです。
この(x、y)座標とでもいいましょうか。これをメモリの位置に置き換えてくれている分
パソコンは別の仕事をしているようです。
なので、
HeapAllocでメモリを確保して、どこに書き込むかは人間側で計算し管理して
書き込んでいきます。計算もそうやってすることでちょっとは早くなるかもしれませんよ。
確保したメモリはHeapFreeで必ず開放してあげてください。(と良く言われました)
でないとプログラムが終了だか電源きるまで確保されたままなので
パソコンがフリーズする原因となりかねません(受け売りでーす)
私もN88BASICで育った人間で、ABしかほぼ使えません。
使えるものを全て駆使してやりたいことが出来ればそれで良いと思いますよ。
色々突っ込みどころが満載な返答ですが、上から目線だとか文盲だとかは
重々承知しておりますので、苦笑いでスルーされますようお願い申し上げます。
こんばんは。
おそらく、実験的な事を繰り返して頭を捏ねているのかなと勝手に推察します。 云十年前はじめてパソコンに触れていた頃に同じような事をいっぱいしました。 回答だと決め付けられたプログラムを勉強するのではなく 自ら回答を探すからこそ、発想が思わぬ回答を持ち出して愉快になることが 多々あるかと思います。 しかし、トモカズさんは大人ですね。。。これからも頑張ってください。
さてさて、計算速度を上げたいとの事ですが 多次元配列は、何をするにも遅いと聞いた事があります。 ですので、まず第一に多次元配列ではない方法でも実験をされてはいかがでしょうか。 あと、このプログラムを組み込んで行く先の都合にもよりますが、 式を見ると計算の桁数がとても多くなりますね。ですので 必要な時に必要な部分だけ計算をするのも体感速度を上げてくれます。 また、数式を出来るだけ計算しておいてあげるのも一つだと思います。 (x*2)*(x*3)のような式であれば、これを展開しておいたほうが速いかもしれません。
私が、速度を上げる時はパソコン任せの部分を人間が管理することで パソコンの負担を減らしてやるってのが良くやる手です。
多次元でも、メモリの並びは一直線上に並んでいるものと考えて良いそうです。 (10,10)の多次元で(0,0)の場所が0番地だとすると (0,1)は1番地、(0,2)は2番地、(0,9)は9番地となって次の (1,0)は10番地という感じだそうです。 この(x、y)座標とでもいいましょうか。これをメモリの位置に置き換えてくれている分 パソコンは別の仕事をしているようです。 なので、 HeapAllocでメモリを確保して、どこに書き込むかは人間側で計算し管理して 書き込んでいきます。計算もそうやってすることでちょっとは早くなるかもしれませんよ。 確保したメモリはHeapFreeで必ず開放してあげてください。(と良く言われました) でないとプログラムが終了だか電源きるまで確保されたままなので パソコンがフリーズする原因となりかねません(受け売りでーす)
私もN88BASICで育った人間で、ABしかほぼ使えません。 使えるものを全て駆使してやりたいことが出来ればそれで良いと思いますよ。
色々突っ込みどころが満載な返答ですが、上から目線だとか文盲だとかは 重々承知しておりますので、苦笑いでスルーされますようお願い申し上げます。
|
|
|
投稿記事 |
Posted: 2010年5月08日(土) 02:12 |
|
|
|
|
|
「読む気も失せる」コードで、申し訳ないです。
(これでも、シンプルにしたつもりです)
>なんでCharが速いと思ったのだろうか。
どんなCPUであれ、16Bitより8Bitの方が処理速度について有利だと思ったからです。
違っています?何だかトンチンカンな質問になってしまっているみたいですね。
ごめんなさい。
>計算量に気をくばるべきだし、
もちろん、計算量や計算式の最適化も考えています。
それもやりつつ、型による処理速度向上を考えたわけです。
>ABを使うなといいたい
すみません。唯一(どうにか)使えるのがABなのです。
「読む気も失せる」コードで、申し訳ないです。 (これでも、シンプルにしたつもりです)
>なんでCharが速いと思ったのだろうか。 どんなCPUであれ、16Bitより8Bitの方が処理速度について有利だと思ったからです。 違っています?何だかトンチンカンな質問になってしまっているみたいですね。 ごめんなさい。
>計算量に気をくばるべきだし、 もちろん、計算量や計算式の最適化も考えています。 それもやりつつ、型による処理速度向上を考えたわけです。
>ABを使うなといいたい すみません。唯一(どうにか)使えるのがABなのです。
|
|
|
投稿記事 |
Posted: 2010年4月25日(日) 16:33 |
|
|
|
|
|
読む気も失せるコードで見てないけど、なんでCharが速いと思ったのだろうか。
どのCPUかわからないけど、32ビットなら32ビット型を54ビットなら64ビット型を使えばいい。
そもそもほんとうにスピードが必要なら、型による速度よりも計算量に気をくばるべきだし、
ABを使うなといいたい。もっと速度の出る処理系を使うべき。
読む気も失せるコードで見てないけど、なんでCharが速いと思ったのだろうか。
どのCPUかわからないけど、32ビットなら32ビット型を54ビットなら64ビット型を使えばいい。
そもそもほんとうにスピードが必要なら、型による速度よりも計算量に気をくばるべきだし、 ABを使うなといいたい。もっと速度の出る処理系を使うべき。
|
|
|
投稿記事 |
Posted: 2010年4月25日(日) 14:53 |
|
|
|
|
|
申し訳ありません。
投稿に名前を入力し忘れてしまいました。
申し訳ありません。 投稿に名前を入力し忘れてしまいました。
|
|
|
投稿記事 |
Posted: 2010年4月25日(日) 07:58 |
|
|
|
|
|
記事の件名: |
変数 CharからIntegerへの変換とスピードアップ |
引用付きで返信する |
|
変数の型を最適化してスピードアップを図りたいと思っています。
現在は、Integer型を使用していますが、変数の置き換え、計算等を数多くするので、Char型が有利であろうと考えました。
しかし、一部の計算でChar型を超えてしまう計算が含まれているので、その箇所をIntegerに変換しながら計算する手法としてみました。
しかし、その「変換しながら」にコストがかかってしまい、本末転倒と言いますか、今ひとつの結果になってしまいました。
以下のサンプルで、「*TEST01-00」がInteger同士の計算
「*TEST01-02」がChar型からIntegerへ変換しながらの計算です。
もっと、効率的(スピード的に有利な)方法が、あったらご教授いただければと存じます。
宜しくお願いいたします。
コード:
#N88BASIC
Dim P%[9,9,59] AS Integer
Dim R%[9,9,59] AS Char
Dim TA1% AS Integer
Dim X AS Char
Dim Y AS Char
Dim I$ AS STRING
Dim dwStart AS int64
Dim dwEnd AS int64
Dim TIMECOUNT AS int64
Dim CT AS Int64
Dim CT2 AS Int64
Dim N AS Char
N=1
Randomize
FOR X=1 TO 8
FOR Y=1 TO 8
P%(X,Y,N)=Int(Rnd()*3)
R%(X,Y,N)=P%(X,Y,N) AS Char
NEXT
NEXT
PRINT "計算スピードテスト"
CT2=20000000
Print
Print "Integer(通常)"
dwStart = GetTickCount()
FOR CT=0 TO CT2:GOSUB *TEST01-00:NEXT
PRINT TA1%
GOSUB *TIMEPRINT
Print "Char(Integerへ変換しながら計算)"
dwStart = GetTickCount()
FOR CT=0 TO CT2:GOSUB *TEST01-02:NEXT
PRINT TA1%
GOSUB *TIMEPRINT
I$=Input$(1)
END
*TIMEPRINT
dwEnd = GetTickCount()
TIMECOUNT=(dwEnd-dwStart)/100
PRINT TIMECOUNT/10;"秒"
RETURN
*TEST01-00
TA1%=P%[1,1,N]+P%[1,2,N]*3+P%[1,3,N]*9+P%[1,4,N]*27+P%[1,5,N]*81+P%[1,6,N]*243+P%[1,7,N]*729+P%[1,8,N]*2187
RETURN
*TEST01-01 '遅いのでボツ
TA1%=(((((((P%[1,8,N]*3+P%[1,7,N])*3+P%[1,6,N])*3+P%[1,5,N])*3+P%[1,4,N])*3+P%[1,3,N])*3+P%[1,2,N])*3+P%[1,1,N])
*TEST01-02
TA1%=R%[1,1,N] AS Integer+R%[1,2,N] AS Integer*3+R%[1,3,N] AS Integer*9+R%[1,4,N] AS Integer*27+R%[1,5,N] AS Integer*81+R%[1,6,N] AS Integer*243+R%[1,7,N] AS Integer*729+R%[1,8,N] AS Integer*2187
RETURN
[/quote]
変数の型を最適化してスピードアップを図りたいと思っています。
現在は、Integer型を使用していますが、変数の置き換え、計算等を数多くするので、Char型が有利であろうと考えました。
しかし、一部の計算でChar型を超えてしまう計算が含まれているので、その箇所をIntegerに変換しながら計算する手法としてみました。
しかし、その「変換しながら」にコストがかかってしまい、本末転倒と言いますか、今ひとつの結果になってしまいました。
以下のサンプルで、「*TEST01-00」がInteger同士の計算 「*TEST01-02」がChar型からIntegerへ変換しながらの計算です。
もっと、効率的(スピード的に有利な)方法が、あったらご教授いただければと存じます。
宜しくお願いいたします。
[code] #N88BASIC
Dim P%[9,9,59] AS Integer Dim R%[9,9,59] AS Char Dim TA1% AS Integer Dim X AS Char Dim Y AS Char Dim I$ AS STRING Dim dwStart AS int64 Dim dwEnd AS int64 Dim TIMECOUNT AS int64 Dim CT AS Int64 Dim CT2 AS Int64 Dim N AS Char
N=1
Randomize
FOR X=1 TO 8 FOR Y=1 TO 8 P%(X,Y,N)=Int(Rnd()*3) R%(X,Y,N)=P%(X,Y,N) AS Char NEXT NEXT
PRINT "計算スピードテスト" CT2=20000000 Print
Print "Integer(通常)" dwStart = GetTickCount() FOR CT=0 TO CT2:GOSUB *TEST01-00:NEXT PRINT TA1% GOSUB *TIMEPRINT
Print "Char(Integerへ変換しながら計算)" dwStart = GetTickCount() FOR CT=0 TO CT2:GOSUB *TEST01-02:NEXT PRINT TA1% GOSUB *TIMEPRINT
I$=Input$(1) END
*TIMEPRINT dwEnd = GetTickCount() TIMECOUNT=(dwEnd-dwStart)/100 PRINT TIMECOUNT/10;"秒" RETURN
*TEST01-00 TA1%=P%[1,1,N]+P%[1,2,N]*3+P%[1,3,N]*9+P%[1,4,N]*27+P%[1,5,N]*81+P%[1,6,N]*243+P%[1,7,N]*729+P%[1,8,N]*2187 RETURN
*TEST01-01 '遅いのでボツ TA1%=(((((((P%[1,8,N]*3+P%[1,7,N])*3+P%[1,6,N])*3+P%[1,5,N])*3+P%[1,4,N])*3+P%[1,3,N])*3+P%[1,2,N])*3+P%[1,1,N])
*TEST01-02 TA1%=R%[1,1,N] AS Integer+R%[1,2,N] AS Integer*3+R%[1,3,N] AS Integer*9+R%[1,4,N] AS Integer*27+R%[1,5,N] AS Integer*81+R%[1,6,N] AS Integer*243+R%[1,7,N] AS Integer*729+R%[1,8,N] AS Integer*2187 RETURN
[/quote][/code]
|
|
|
投稿記事 |
Posted: 2010年4月25日(日) 07:56 |
|
|
|
|