我正在开发一个扑克应用程序,我几乎完成了它,我正在寻找改进,我想知道的一件事是我应该改变我的主循环方法方法吗?目前它通过使用尾递归调用进行循环。然而,我的朋友建议我将其切换到迭代,因为它使用while循环并且循环不需要堆栈空间。这是我现在的代码。
private async Task Turns()
{
_turns = ReturnTurns();
GC.KeepAlive(Updates);
if (!Player.FoldTurn && Player.Chips > 0)
{
if (Player.Turn)
{
SetPlayerStuff(true);
Call -= Player.PreviousCall;
_up = int.MaxValue;
_turnCount++;
Bot1.Turn = true;
_restart = true;
}
}
if (!Player.Turn)
{
await Flip(0);
}
if (Player.FoldTurn || !Player.Turn || Player.Chips <= 0)
{
Call = TempCall;
if (StatusLabels[Player.EnumCasted].Contains(RepetitiveVariables.Fold))
{
Bot1.Turn = true;
}
SetPlayerStuff(false);
Bot1 = (Bot)await RotateTurns(Bot1, Bot1.EnumCasted);
Bot2 = (Bot)await RotateTurns(Bot2, Bot2.EnumCasted);
Bot3 = (Bot)await RotateTurns(Bot3, Bot3.EnumCasted);
Bot4 = (Bot)await RotateTurns(Bot4, Bot4.EnumCasted);
Bot5 = (Bot)await RotateTurns(Bot5, Bot5.EnumCasted);
_restart = false;
}
if (!_restart)
{
await Turns();
}
}
我觉得它看起来应该像循环一样:
private async Task Turns()
{
while (true)
{
_turns = ReturnTurns();
GC.KeepAlive(Updates);
if (!Player.FoldTurn && Player.Chips > 0)
{
if (Player.Turn)
{
SetPlayerStuff(true);
Call -= Player.PreviousCall;
_up = int.MaxValue;
_turnCount++;
Bot1.Turn = true;
_restart = true;
}
}
if (!Player.Turn)
{
await Flip(0);
}
if (Player.FoldTurn || !Player.Turn || Player.Chips <= 0)
{
Call = TempCall;
if (StatusLabels[Player.EnumCasted].Contains(RepetitiveVariables.Fold))
{
Bot1.Turn = true;
}
SetPlayerStuff(false);
Bot1 = (Bot) await RotateTurns(Bot1, Bot1.EnumCasted);
Bot2 = (Bot) await RotateTurns(Bot2, Bot2.EnumCasted);
Bot3 = (Bot) await RotateTurns(Bot3, Bot3.EnumCasted);
Bot4 = (Bot) await RotateTurns(Bot4, Bot4.EnumCasted);
Bot5 = (Bot) await RotateTurns(Bot5, Bot5.EnumCasted);
_restart = false;
}
if (!_restart)
{
continue;
}
break;
}
}
答案 0 :(得分:2)
通常,JIT无法用循环替换递归。这是一个相当深奥的优化方案。
这里甚至没有发挥作用,因为异步方法在内部使用非常不同的调用机制。
此代码将消耗与递归深度成比例的“堆栈空间”。 (它不一定是使用异步方法的堆栈空间。可以是链表空间形式的堆空间。)
从代码质量的角度来看,我发现循环非常可取,因为递归并不是大多数人习惯的。在这里,确实没有算法需要递归。似乎错误的工作工具。我认为你已经使用递归作为“goto”的替代,因为所有这一切都会跳回到方法的开头。
你可以让跳跃条件更清洁一点:
if (!_restart) break;