Sub や Function 呼び出しのオーバーヘッドを少しでもなくしたいのですが、再帰呼出しが不要の場合、変数の宣言を Dim -> Static にすることで効果は得られるのでしょうか?、それともほかに何か有効な方法はあるのでしょうか?、よろしくお願いします。
> 効果は得られるのでしょうか?、
人に聞く前に、実際に自分で試しましょう。その方が確実ですよ。
…多分、おそらく効果はほとんど得られないと思います。
Dim → Static にすれば、変数の再確保に要する時間を短縮できるかも知れませんが、変数のサイズがよほど巨大でない限り、誤差範囲程度の違いしか得られないと思います。
> 何か有効な方法はあるのでしょうか?
オーバーヘッドを少なくするには、まず、処理のどの部分がボトルネックになっているかを調べることが重要です。
例えば、
Sub Test()
Dim I As Integer
For I = 1 To 10
Call 処理A
Netx
Call 処理B
End Sub
のような処理があったと想定してください。
この時、処理Aは 1回あたり 0.1秒、処理Bは30秒かかっているとします。(合計31秒)
このような場合、処理Aを大幅に見直して、元の10%の時間(0.01秒)で終わるように
修正するよりは、処理Bを少しだけ見直し、元の95%の時間(28.5秒)で終わるように
修正した方が、結果としては、高い効果を得られますよね。
>人に聞く前に、実際に自分で試しましょう。その方が確実ですよ
おっしゃるとおりです、全体のロジックを見直して、少しだけ高速化できました。
(私のケースの場合Dimをstaticに変えただけでは体感できる程の効果はありませんでした)、ありがとうございました。
ただ、知識として知っておきたいのでVBのローカル変数はどのように生成されるのか良かったら教えてください。
都合で週明けまでRes出来ませんがよろしくお願いします。
VBに限らず、一般にローカル変数(自動変数)は、
関数呼び出しの際にスタック上にスタックフレームを生成し、
ベースポインタからのオフセットとして定義されます。
ちなみに、関数の引数もベースポインタからのオフセットで
アクセスされます。(メモリ構造上はベースポインタの
-側にあるか+側にあるかの違いです。)
また、関数戻り値はアキュムレータレジスタ経由で戻されます。
なお、コンパイラの最適化スイッチによっては
自動変数をスタック上ではなくレジスタに割り当てるものもあります。
詳しくはアセンブラの解説書を参照してください。
staticにすれば、データセクションにおかれるので、
最悪の場合、HDDに退避されている可能性もありますよね。(仮想メモリとして)
ローカルならば、スタック領域なので、それが起こる確立は
かなり低いと思いますよ。(たぶん)
補足
staticな変数が、長い間アクセスされなければ、
たとえHDDに退避されてなくとも、
仮想メモリから実メモリへのマッピングが生じるでしょう。
スタックならば、その関数に入った時のスタックに生成するので、
セカンドキャッシュなど、高速なメモリが使われる可能性が高いと思います。
(たぶん)
皆さんどうもありがとうございます、なるほどVBもローカルはスタックフレームに生成されるわけですね、ということはよほど大きな領域を取らない限り、変数はいくつ(限度はありますけど)定義してもほとんどオーバーヘッドは無いし、定義した数による処理時間の変化も無いということですね。
それよりstaticのほうが速度を低下させる要因を持っているとは・・・、質問してみてよかったです、ありがとうございました。
ツイート | ![]() |