値を返す関数をいくつか作り、実行すると、スタック領域不足というエラーが出ました。
エラーの場所は、関数中の値を返す命令の部分です。
最初は、エラーの出た関数をコメントアウトし実行させると、その次の関数の値を返すところでエラーが出ます。
この問題はどのように解決したらよいでしょうか?
今の所関数の返す値をグローバル変数に置き換えるという手段をとってます。
後、VBで早い処理をさせるポイントなど教えて欲しいです。
よろしくお願いします。
いくつか、っていくつぐらいなんでしょう?
スタック領域なのでローカル変数を使いすぎたり
関数の中から関数を呼び出して・・・を繰り返すと
そういうエラーがでやすくはなりますが・・・。
上記が原因であれば、対策は以下のようなものが考えられます。
・ローカル変数を無駄に使わないようにする。
・関数の引数を減らす。
・配列を固定長ではなく動的変換する
(とたぶん、スタックではなくなる気がするけど、確認してないです。)
・再帰処理とかやってるんであれば、やらないような方法を考える
・文字列の値渡しもスタック使われてるかも。
参照だったら4Byteで済むはずなので、参照渡しに変えてみるとか。
最後の手段として、スタック領域を増やす、
というのもありますが・・・。
VBの場合はコンパイルオプションで変更できないので
コンパイル後に細工することになりますが・・・。
値渡しは変えないほうがパフォーマンス的にはいいです。
スタックもあまり変わらないようです。
引数が五個以上で、固定長配列を使用していると致命的です。
こういう場合は引数を減らすことよりも固定長配列を減らす・なくす
方を優先した方がいいです。
> 値渡しは変えないほうがパフォーマンス的にはいいです。
??VB5ではあきらかに値渡しの方が実行速度が遅いようですが
環境が違うと動作が異なるのでしょうか?
それとも、パフォーマンスが良いとは
もっと別のことを差しているのでしょうか?
一応、確認に使用したコードです。
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Private Sub Command1_Click()
Dim i As Long
Dim a As String
Dim tm As Long
a = "あいうえおかきくけこさしすせそ"
tm = timeGetTime()
For i = 0 To 800000
Call testVal(a)
Next i
tm = timeGetTime() - tm
Me.Caption = tm
End Sub
Private Sub Command2_Click()
Dim i As Long
Dim a As String
Dim tm As Long
a = "あいうえおかきくけこさしすせそ"
tm = timeGetTime()
For i = 0 To 800000
Call testRef(a)
Next i
tm = timeGetTime() - tm
Me.Caption = tm
End Sub
Private Sub testVal(ByVal a As String)
End Sub
Private Sub testRef(ByRef a As String)
End Sub
複数の処理をシングルスレッドで行う場合に変数が変更されるエラーが少なく、
参照するための操作によってパフォーマンスが(ほんのちょっと)僕の環境
(VB.NET、Win2k)では低下します。
僕の環境だけかもしれないのですが。
スタックの使用量は,
参照渡し : 4 byte (変数へのポインタが渡る)値渡し : 8 byte (文字列の長さと文字列へのポインタが渡る)
です。
ただし,文字列が長い場合,文字列自体の複製に時間がかかる可能性はあります。
#以上,VB5sp3からmov eax, espだけ行うDLL関数を呼び出して確認
でもって,
> それとも、パフォーマンスが良いとは
> もっと別のことを差しているのでしょうか?
恐らく……。
こころさんが言われているパフォーマンスは,関数呼び出しにかかるコストのことで,
蜻蛉さんが言われているパフォーマンスは,引数の利用にかかるコストのことですよね。
ツイート | ![]() |