?:运营商与。 If 语句性能
Posted
技术标签:
【中文标题】?:运营商与。 If 语句性能【英文标题】:?: Operator Vs. If Statement Performance 【发布时间】:2010-10-07 12:42:58 【问题描述】:我一直在尝试优化我的代码,使其更加简洁易读,并希望这样做不会导致性能下降。我认为我的更改可能会减慢我的应用程序,但它可能只是在我的脑海中。两者之间是否有任何性能差异:
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
我对可读性的偏好是空合并运算符,我只是不希望它影响性能。
【问题讨论】:
【参考方案1】:您在这里尝试micro-optimize,这通常是一个很大的禁忌。除非您的性能分析表明这是一个问题,否则根本不值得更改。
对于一般用途,正确的答案是更容易维护。
尽管如此,null 合并运算符的 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
,执行四个操作。
在非null
值的情况下,空合并运算符执行四个操作而不是五个操作。
当然,这假设所有 IL 操作都花费相同的时间,但事实并非如此。
无论如何,希望您能看到在这种微观尺度上进行优化会如何迅速开始减少回报。
话虽如此,最后,对于大多数情况,在这种情况下最容易阅读和维护的就是正确答案。
如果您发现这样做的规模被证明是低效的(而且这种情况很少而且相差甚远),那么您应该衡量哪个具有更好的性能,然后进行特定的优化。
【讨论】:
'L_0006: dup' - 在这里显示我自己的无知,但为什么需要在这里复制? 哦,我明白了。如果它不为空,则存储在 000f 并且不会弹出。有道理。 string.IsNullOrEmpty() 怎么样? @SkippyFire:这将需要更多的 IL 指令,因为必须进行方法调用,并且它只会执行与上述类似的操作。 方法调用可能会在它的 jitted 时被内联,不是吗?【参考方案2】:为了讨论... if/then/else 的运行速度与 ?: 三元运算的运行速度与单级 switch/case 语句一样快。
Here are some performance benchmarks with the C# code.
只有当您开始深入到 2-3 级的情况下,性能才会开始受到严重影响。也就是说,像这个荒谬的例子:
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;
【讨论】:
【参考方案3】:这是机器级代码是高效还是人类可读代码的问题。 当我们让它对我们来说更具可读性时,它使机器能够复杂地解释代码,反之亦然......
【讨论】:
【参考方案4】:在这种情况下几乎没有显着的性能差异。
当性能差异可以忽略不计时,一切都与可读代码有关。
【讨论】:
我将其细化为“在没有显着性能差异的情况下,一切都与可读代码有关。”有时,存在性能差异,有时这种差异很大,在这种情况下,代码可读性可能会退居二线。 这和我说的有什么不同? @chris-ballance 不同之处显然在于强调的地方。【参考方案5】:我认为我的更改可能已经放慢了 关闭我的应用程序,但它可能只是 在我的脑海里。
除非您实际上是在测量性能,否则这一切都在您的头脑中和无谓的猜测中。
(不是特别挑剔你,但是看到一个又一个关于性能微优化的问题(以及许多答案)不包含“测量”一词,真是令人失望。)
【讨论】:
【参考方案6】:我怀疑不会有任何性能差异。
除此之外,我想知道为什么您会担心在这种情况下偏爱一种陈述而不是另一种陈述?我的意思是:性能影响(如果有的话)将是最小的。恕我直言,这将是一种微优化,不值得付出努力。 我会选择最易读、最清晰且不担心性能的语句,因为它的影响最小(在这种情况下)。
【讨论】:
最初的编写方式是一堆 if 语句,当我更改它时,似乎该程序的性能受到了一点影响。也许这是一个孤立的事件,但它最能激发我的兴趣。【参考方案7】:恕我直言,针对可读性和理解进行优化 - 与您在现实世界中花费的时间相比,当您在几个月后回到此代码并尝试了解哎呀,你一开始就是这样做的。
【讨论】:
当然,要记住很多程序员都可以阅读? : 语句与常规 if 语句一样快。在某些情况下,它们甚至比使用不带大括号的 if / else 语句更清晰。 我同意。这里的许多帖子都是性能问题,询问无关紧要的细微调整(++ 是否比 +=1 快?)。速度来自于算法的复杂性:减少大量的内存副本,快速搜索容器,适当地散列。细微的调整对性能没有影响。 -1:虽然 chublogga 的观点都是真实有效的,而且措辞得当,但它们并没有回答最初的问题。 OP是个大人,可以自己做架构/可读性的选择,casperOne的回答真的是对具体性能问题更有趣更直接的回答。 我没有回答最初的问题,因为这是一个错误的问题。 假设如果人类能够看到明显的东西,编译器就会足够聪明地看到甚至超越,难道不安全吗?以上是关于?:运营商与。 If 语句性能的主要内容,如果未能解决你的问题,请参考以下文章