2017-02-14 4 views
0

実行時にフレームを返す再帰関数を強制するにはどうすればよいですか?再帰関数がスキップフレームを生成するように強制するには?

私は、再帰関数の異なる段階でyield関数を配置しようとしました。

私は何が起こっているのか分かりません。なぜなら、1000回の再帰ごとに時間を印刷するための条件は無視され、およそ100万回の再帰のみを生成して出力するからです。ピックアップすべき印刷コマンドの90%はコードによって無視され、表示されません。 ランタイムは1〜2分ごとに実行され、一度に12のステートメントを出力します。

これは私が管理しているコードの中で最も速いバージョンです。 yield文を上下に変更すると、ランタイムが完全にフリーズすることがあり、10分間何も起こりません。

なぜフリーズし、どのように変更できますか?

//A working 3D floodfill function that reads and writes a boolean voxel array: 

private var maxAbort = 1000000000; 

function boundary(x:int, y:int, z:int): IEnumerator //floodfill algo 
{ 
    if (read3DboolArray(x,y,z)==false && bcnt<maxAbort){//pprevent stackoverflow with limit FASTER 
     if (x >= 0 && x < bsizex && y >= 0 && y < bsizey && z >= 0 && z < bsizez) 
     {   

      write3DboolArray(x,y,z,true); 


      boundary(x+1,y,z); 
      boundary(x-1,y,z);  yield WaitForFixedUpdate(); 
      boundary(x,y+1,z); 
      boundary(x,y-1,z); // yield WaitForFixedUpdate(); 
      boundary(x,y,z+1); 
      boundary(x,y,z-1); 
     } 

     if (bcnt % 1000== 0)//mark new start if ended this recursion run 
     { 
      print(bcnt+ " ------  " + 
       (Time.realtimeSinceStartup-tt)); 
      bcnt+=1; 

      yield WaitForFixedUpdate(); 
     } 
    } else return; 
} 

本方法における収率を用い.NETフレームワーク2.0

+0

これを一般的なスタックよりも優れた方法で解決しました。結果は次のとおりです。https://unity3dmc.blogspot.fr/2017/02/ultimate-3d-floodfill-scanline.html –

答えて

2

のフォークであるUnity3DのMonoDevelopのランタイムを使用してい本質的に反復子のコンストラクタに方法を回します。イテレータが実際に何か意味のあることをするためには、実際にイテレータを反復処理する必要があります。

boundary(x+1,y,z); 
    boundary(x-1,y,z);  yield WaitForFixedUpdate(); 
    boundary(x,y+1,z); 
    boundary(x,y-1,z); // yield WaitForFixedUpdate(); 
    boundary(x,y,z+1); 
    boundary(x,y,z-1); 

これは基本的に2つの列挙子を作成し、それからそれらを放棄します。再帰的な利回りが機能するには、すべての結果を最初のコールサイトまですべて戻す必要があります。

このような作業負荷に対して歩留まりとコルーチンを使用すると、非常に非効率的です。私はアルゴリズムを改造して反復的に(by using a stack for example、明らかにスタックオーバーフローの問題に役立つでしょう)、またはこれを別のワーカースレッドにオフロードすることを提案します。

+0

ありがとうございました。その反復版。おそらくそれはいくつかの段階で効果を発揮するだろう。再帰的なバージョンは6千万のボクセルを処理することができ、私はちょうど600mnのボクセルバージョンを実行していますが、それは非常に遅いということだけです。 [私がそれを書いたときには、より良い3D floodfillコードになります。 –

関連する問題