代码之家  ›  专栏  ›  技术社区  ›  Jon

?:运算符与if语句性能

  •  32
  • Jon  · 技术社区  · 17 年前

    我一直在尝试优化我的代码,使其更加简洁和可读,希望这样做不会导致性能下降。我认为我的更改可能会减慢我的应用程序速度,但它可能只是在我的头脑中。以下两者之间是否存在性能差异:

    Command.Parameters["@EMAIL"].Value = email ?? String.Empty;
    

    和

    Command.Parameters["@EMAIL"].Value = (email == null) ? String.Empty: email;
    

    和

    if (email == null)
    {
        Command.Parameters["@EMAIL"].Value = String.Empty
    }
    else
    {
        Command.Parameters["@EMAIL"].Value = email
    }
    

    我对可读性的偏好是空合并运算符,我只是不希望它影响性能。

    7 回复  |  直到 7 年前
        1
  •  67
  •   PhilChuang    17 年前

    imho,针对可读性和理解性进行优化-与您在现实世界中花费的时间相比,任何运行时性能的提高都可能是最小的,当您在几个月内回到这段代码中,并尝试了解您最初在做什么。

        2
  •  71
  •   Servy    7 年前

    你在努力 micro-optimize 在这里,这通常是一个很大的禁忌。除非你有性能分析显示这是一个问题,它甚至不值得改变。

    一般来说,正确的答案是任何更容易维护的东西。

    不过,对于它而言,空合并运算符的IL是:

    L_0001: ldsfld string ConsoleApplication2.Program::myString
    L_0006: dup 
    L_0007: brtrue.s L_000f
    L_0009: pop 
    L_000a: ldsfld string [mscorlib]System.String::Empty
    L_000f: stloc.0 
    

    开关的IL是:

    L_0001: ldsfld string ConsoleApplication2.Program::myString
    L_0006: brfalse.s L_000f
    L_0008: ldsfld string ConsoleApplication2.Program::myString
    L_000d: br.s L_0014
    L_000f: ldsfld string [mscorlib]System.String::Empty
    L_0014: stloc.0 
    

    对于 null coalescing operator ,如果值为 null ,然后执行六个语句,而 switch ,执行四个操作。

    如果不是 无效的 值,空合并运算符执行四个操作,而不是五个操作。

    当然,这假设所有的IL操作都花费相同的时间,但事实并非如此。

    不管怎样,希望你能看到,在这种微观规模上的优化是如何开始迅速减少收益的。

    也就是说,在大多数情况下,在这种情况下,最容易阅读和维护的内容都是正确的答案。

    如果您发现这样做的规模被证明是低效的(并且这些情况很少而且相距很远),那么您应该衡量一下哪个性能更好,然后进行特定的优化。

        3
  •  18
  •   Brian    17 年前

    我想我的变化可能已经放缓了 关闭我的应用程序,但它可能只是 在我脑海里。

    除非你真的 测量 性能,这一切都在你的头脑和闲置的猜测。

    (不是特别挑剔你,但对于不包含“度量”一词的性能微优化(以及许多答案),一个接一个的问题是令人失望的。)

        4
  •  7
  •   Frederik Gheysels    17 年前

    我怀疑不会有任何性能差异。

    除此之外,我想知道,在这种情况下,为什么你会有任何倾向于一种说法而不是另一种说法的顾虑?我的意思是:性能影响(如果应该有的话)是最小的。imho,这是一种微观优化,不值得这么做。
    我会选择最可读、最清晰、不担心性能的语句,因为它的影响最小(在本例中)。

        5
  •  7
  •   Chris Ballance    15 年前

    在这种情况下,几乎没有显著的性能差异。

    当性能差异可以忽略不计时,这就是 可读代码 .

        6
  •  3
  •   WorkRelated    12 年前

    为了讨论…如果/那么/否则运行速度和?:三元操作,速度与单个级别开关/case语句一样快。

    Here are some performance benchmarks with the C# code.

    只有当您开始深入了解2-3个级别的case语句时,性能才会受到严重影响。也就是说,类似于这个荒谬的例子:

    switch (x % 3)
        {
            case 0:
                switch (y % 3)
                {
                    case 0: total += 3;
                        break;
                    case 1: total += 2;
                        break;
                    case 2: total += 1;
                        break;
                    default: total += 0;
                        break;
                }
                break;
            case 1:
                switch (y % 3)
                {
                    case 0: total += 3;
                        break;
                    case 1: total += 2;
                        break;
                    case 2: total += 1;
                        break;
                    default: total += 0;
                        break;
                }
                break;
        case 2:
                switch (y % 3)
                {
                    case 0: total += 3;
                        break;
                    case 1: total += 2;
                        break;
                    case 2: total += 1;
                        break;
                    default: total += 0;
                        break;
                }
                break;
        default:
            switch (y % 3)
            {
                case 0: total += 3;
                    break;
                case 1: total += 2;
                    break;
                case 2: total += 1;
                    break;
                default: total += 0;
                    break;
            }
            break;
        }
    
        7
  •  1
  •   user1978134    13 年前

    这是一个机器级代码是有效的还是人类可读的代码的问题。 当我们使它对我们更具可读性时,它使机器对代码进行复杂的解释,反之亦然…