正しく関数から値を返すには?


ALW  2002-06-01 06:42:30  No: 75673

値を返す関数をいくつか作り、実行すると、スタック領域不足というエラーが出ました。
エラーの場所は、関数中の値を返す命令の部分です。
最初は、エラーの出た関数をコメントアウトし実行させると、その次の関数の値を返すところでエラーが出ます。
この問題はどのように解決したらよいでしょうか?
今の所関数の返す値をグローバル変数に置き換えるという手段をとってます。
後、VBで早い処理をさせるポイントなど教えて欲しいです。
よろしくお願いします。


こころ  URL  2002-06-01 09:13:14  No: 75674

いくつか、っていくつぐらいなんでしょう?
スタック領域なのでローカル変数を使いすぎたり
関数の中から関数を呼び出して・・・を繰り返すと
そういうエラーがでやすくはなりますが・・・。

上記が原因であれば、対策は以下のようなものが考えられます。
・ローカル変数を無駄に使わないようにする。
・関数の引数を減らす。
・配列を固定長ではなく動的変換する
  (とたぶん、スタックではなくなる気がするけど、確認してないです。)
・再帰処理とかやってるんであれば、やらないような方法を考える
・文字列の値渡しもスタック使われてるかも。
  参照だったら4Byteで済むはずなので、参照渡しに変えてみるとか。


Say  2002-06-01 22:13:27  No: 75675

最後の手段として、スタック領域を増やす、
というのもありますが・・・。
VBの場合はコンパイルオプションで変更できないので
コンパイル後に細工することになりますが・・・。


蜻蛉  URL  2002-06-02 06:05:26  No: 75676

値渡しは変えないほうがパフォーマンス的にはいいです。
スタックもあまり変わらないようです。

引数が五個以上で、固定長配列を使用していると致命的です。
こういう場合は引数を減らすことよりも固定長配列を減らす・なくす
方を優先した方がいいです。


こころ  URL  2002-06-02 12:00:39  No: 75677

> 値渡しは変えないほうがパフォーマンス的にはいいです。
??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


蜻蛉  URL  2002-06-02 18:33:17  No: 75678

複数の処理をシングルスレッドで行う場合に変数が変更されるエラーが少なく、
参照するための操作によってパフォーマンスが(ほんのちょっと)僕の環境
(VB.NET、Win2k)では低下します。

僕の環境だけかもしれないのですが。


YuO  2002-06-02 20:25:06  No: 75679

スタックの使用量は,
参照渡し : 4 byte (変数へのポインタが渡る)値渡し   : 8 byte (文字列の長さと文字列へのポインタが渡る)
です。
ただし,文字列が長い場合,文字列自体の複製に時間がかかる可能性はあります。
#以上,VB5sp3からmov eax, espだけ行うDLL関数を呼び出して確認

でもって,
> それとも、パフォーマンスが良いとは
> もっと別のことを差しているのでしょうか?
恐らく……。
こころさんが言われているパフォーマンスは,関数呼び出しにかかるコストのことで,
蜻蛉さんが言われているパフォーマンスは,引数の利用にかかるコストのことですよね。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加