【问题标题】:Method optimization方法优化
【发布时间】:2016-03-26 20:01:11
【问题描述】:

我有一个 void 函数,其中有很多 if 语句,并且所有这些语句都是必需的,我真的无法删除任何东西。但我觉得它可以做得更好。使用一些LINQ.Where、类或类似的东西。我想以尽可能少的字符优化和表达void Smooth

    void Smooth(ref int botChips, ref bool botTurn, Label botStatus, int name, int n, int r) {
        Random rand = new Random();
        int rnd = rand.Next(1, 3);
        if (rounds == 0 || rounds == 1)
        {
            if (call <= 0)
            {
                Check(ref botTurn, botStatus);
            }
            else
            {
                if (call >= RoundN(botChips, n))
                {
                    Call(ref botChips, ref botTurn, botStatus);
                }
                else
                {
                    if (botChips >= call * 2)
                    {
                        Raise *= 2;
                        Raised(ref botChips, ref botTurn, botStatus);
                    }
                    else
                    {
                        Call(ref botChips, ref botTurn, botStatus);
                    }
                }
            }
        }
        if (rounds == 2 || rounds == 3)
        {
            if (call <= 0)
            {
                if (rnd == 1)
                {
                    Raise = RoundN(botChips, r);
                    Raised(ref botChips, ref botTurn, botStatus);
                }
                else if (rnd!=1 && rounds==2)
                {
                    Check(ref botTurn, botStatus);
                }
            }
            else
            {
                if (call >= RoundN(botChips, r))
                {
                    if (botChips > call)
                    {
                        Call(ref botChips, ref botTurn, botStatus);
                    }
                    if (botChips <= call)
                    {
                        raising = false;
                        botTurn = false;
                        botChips = 0;
                        botStatus.Text = "Call " + call;
                        tbPot.Text = (int.Parse(tbPot.Text) + call).ToString();
                    }
                }
                else
                {
                    if (Raise <= (RoundN(botChips, r)) / 2)
                    {
                        Raise = RoundN(botChips, r);
                        Raised(ref botChips, ref botTurn, botStatus);
                    }
                    else
                    {
                        Raise *= 2;
                        Raised(ref botChips, ref botTurn, botStatus);
                    }
                }
            }
        }
    }

RoundN方法

    private static double RoundN(int sChips, int n) {
        double a = Math.Round((sChips / n) / 100d, 0) * 100;
        return a;
    }

Fold方法

    private void Fold(ref bool sTurn, ref bool SFTurn, Label sStatus) {
        raising = false;
        sStatus.Text = "Fold";
        sTurn = false;
        SFTurn = true;
    }

Check方法

    private void Check(ref bool cTurn, Label cStatus) {
        cStatus.Text = "Check";
        cTurn = false;
        raising = false;
    }

Call方法

    private void Call(ref int sChips, ref bool sTurn, Label sStatus) {
        raising = false;
        sTurn = false;
        sChips -= call;
        sStatus.Text = "Call " + call;
        tbPot.Text = (int.Parse(tbPot.Text) + call).ToString();
    }

Raised方法

    private void Raised(ref int sChips, ref bool sTurn, Label sStatus) {
        sChips -= Convert.ToInt32(Raise);
        sStatus.Text = "Raise " + Raise;
        tbPot.Text = (int.Parse(tbPot.Text) + Convert.ToInt32(Raise)).ToString();
        call = Convert.ToInt32(Raise);
        raising = true;
        sTurn = false;
    }

【问题讨论】:

  • 您尝试分析了吗?顺便说一句,我将只定义一次 Random 并将这个大方法分成几个较小的方法 (Ctrl+R, M)
  • 我知道这不是你问的,但这是对new Random 的非常危险的用法;如果您在循环中调用Smooth,它可以使用相同的种子。您应该将rand 设为实例变量并在构造函数中对其进行初始化。
  • 感谢您的回答!不,我没有尝试分析,我会修复new Random
  • 定义优化。您是否想分析输入值并尽可能快地重构最常见输入的代码,而不管它有多神秘?您希望以尽可能少的字符表示代码吗?最少的内存缓存未命中? ...
  • 问“你能把这段代码写多短?”的地方是在拼图网站上问一个代码高尔夫问题。但较短的代码很少是更易于理解、更快、更好的代码。它只是更短。如果你想要的是让你的代码更优雅和更容易理解,那么这与让它更短有很大的不同。首先消除所有这些参考。如果您正在计算值,请将值传回而不是修改变量。

标签: c# .net optimization readability


【解决方案1】:

Smooth 方法可以在某些方面简化(或者用你的话说:优化?):

  1. 若要删除条件 (if-else) 嵌套块,请考虑将早期的 return 用于两者中更简单或没有进一步延续的条件。这样,您可以删除“难以阅读”的嵌套块。
  2. 为避免“重复”块,应将具有相同操作的块视为组合在一起,而不是分开。
  3. 想想反转条件是否有助于简化代码
  4. 利用您所知道的有关语言评估的任何有益行为。例如for C#,在if (a || b)这样的条件语句的参数中,left表达式(即:a)将首先被求值——这被称为Short Circuit Evaluation .
  5. 在不显着降低可读性的情况下,尽可能考虑使用Ternary operator 替换if-else 块。
  6. 声明变量,您将多次使用而不只更改值一次
  7. 注意重叠(双重/重复)情况!
  8. 使用正确数据类型帮助!

对于您的情况,简化的代码可以是这样的

uint rounds = 0; //read 8.
void Smooth(ref int botChips, ref bool botTurn, Label botStatus, int name, int n, int r) {
    Random rand = new Random();
    int rnd = rand.Next(1, 3);
    if (rounds <= 1) { //read 8.
        if (call <= 0) {
            Check(ref botTurn, botStatus); //since your Check doesn't change rounds, this is legal                  
            return; //read 1. early return                  
        } //beyond this call > 0
        if (call >= RoundN(botChips, n) || botChips < call * 2) { //read 2., 3., 4., and 7.
            Call(ref botChips, ref botTurn, botStatus);
            return; //read 1.
        } //beyond this is the opposite of both conditions
        Raise *= 2;
        Raised(ref botChips, ref botTurn, botStatus);
    }

    if (rounds == 2 || rounds == 3) {
        if (call <= 0) {
            if (rnd == 1) { //call <= 0, rnd == 1, similar to the block on call < rNBChips, may potentially be further simplified
                Raise = RoundN(botChips, r);
                Raised(ref botChips, ref botTurn, botStatus);
            } else if (rounds == 2) //read 7. rnd is definitely not 1, no need for further check
                Check(ref botTurn, botStatus);
            return; //read 1. this is valid since you don't want to continue
        }
        double rNBChips = RoundN(botChips, r); //read 6. this way you avoid multiple calls. It both shorter and faster
        if (call < rNBChips) { //read 3.
            Raise = Raise <= rNBChips / 2 ? rNBChips : Raise * 2; //read 5.
            Raised(ref botChips, ref botTurn, botStatus);
            return; // read 1.
        }
        if (botChips > call) {
            Call(ref botChips, ref botTurn, botStatus);
            return; //read 1.
        }
        raising = false;
        botTurn = false;
        botChips = 0;
        botStatus.Text = "Call " + call;
        tbPot.Text = (int.Parse(tbPot.Text) + call).ToString();
    }
}

如果没有 cmets,它甚至看起来更紧凑,就像这样

uint rounds = 0;
void Smooth(ref int botChips, ref bool botTurn, Label botStatus, int name, int n, int r) {
    Random rand = new Random();
    int rnd = rand.Next(1, 3);
    if (rounds <= 1) {
        if (call <= 0) {
            Check(ref botTurn, botStatus);              
            return; 
        }
        if (call >= RoundN(botChips, n) || botChips < call * 2) {
            Call(ref botChips, ref botTurn, botStatus);
            return;
        }
        Raise *= 2;
        Raised(ref botChips, ref botTurn, botStatus);
    }

    if (rounds == 2 || rounds == 3) {
        if (call <= 0) {
            if (rnd == 1) {
                Raise = RoundN(botChips, r);
                Raised(ref botChips, ref botTurn, botStatus);
            } else if (rounds == 2)
                Check(ref botTurn, botStatus);
            return;
        }
        double rNBChips = RoundN(botChips, r);
        if (call < rNBChips) {
            Raise = Raise <= rNBChips / 2 ? rNBChips : Raise * 2;
            Raised(ref botChips, ref botTurn, botStatus);
            return;
        }
        if (botChips > call) {
            Call(ref botChips, ref botTurn, botStatus);
            return;
        }
        raising = false;
        botTurn = false;
        botChips = 0;
        botStatus.Text = "Call " + call;
        tbPot.Text = (int.Parse(tbPot.Text) + call).ToString();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    • 2012-05-07
    • 1970-01-01
    相关资源
    最近更新 更多