C#tail递归调用vs迭代(循环)

时间:2016-02-24 12:13:40

标签: c# loops recursion stack iteration

我正在开发一个扑克应用程序,我几乎完成了它,我正在寻找改进,我想知道的一件事是我应该改变我的主循环方法方法吗?目前它通过使用尾递归调用进行循环。然而,我的朋友建议我将其切换到迭代,因为它使用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;
        }
    }

1 个答案:

答案 0 :(得分:2)

通常,JIT无法用循环替换递归。这是一个相当深奥的优化方案。

这里甚至没有发挥作用,因为异步方法在内部使用非常不同的调用机制。

此代码将消耗与递归深度成比例的“堆栈空间”。 (它不一定是使用异步方法的堆栈空间。可以是链表空间形式的堆空间。)

从代码质量的角度来看,我发现循环非常可取,因为递归并不是大多数人习惯的。在这里,确实没有算法需要递归。似乎错误的工作工具。我认为你已经使用递归作为“goto”的替代,因为所有这一切都会跳回到方法的开头。

你可以让跳跃条件更清洁一点:

        if (!_restart) break;