2017-02-14 55 views
0

如何强制递归函数在运行时产生帧?如何强制递归函数生成跳过帧?

我试图把屈服函数的递归函数的不同阶段。

我不明白发生了什么,因为如果条件印刷品时,每1000个递归被忽略,它只是产量和打印大约每100万个递归。应该被拾取的打印命令的90%被代码忽略并且不出现。 运行时每隔1-2分钟产生一次,并一次打印十几条语句。

这是我已成功地编写代码的最快的版本;如果我向上或向下更改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; 
} 

它使用Unity3D的MonoDevelop中运行时它是.NET框架2.0

+0

我用一种比通用堆栈更好的方法解决了这个问题,这里的结果是https://unity3dmc.blogspot.fr/2017/02/ultimate-3d-floodfill-scanline.html –

回答

2

在一个方法使用产率的叉基本上接通方法转化为一个迭代的构造函数。为了让迭代器实际上做一些有意义的事情,你实际上需要迭代它。

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); 

这基本上只是创建了几个普查员,然后抛出他们离开。为了使递归良率起作用,您必须将所有结果返回到初始呼叫站点。

这样做可以用产量和协同程序对这种工作量似乎非常低效。我建议要么试图重塑算法是迭代(by using a stack for example,这也将有明显的堆栈溢出问题的帮助),或卸载到一个单独的工作线程这一点。

+0

谢谢,我发现了一些很好的提示那个迭代版本。可能会在某个阶段实施。目前递归版本可以做60mn体素,我只是运行一个600mn体素版本,只是速度很慢。当我写它时,会有更好的3D填充码。 –