编辑:
增加了一个可以使用if-else语句但不能使用条件操作符的示例。
在回答之前,请先看一下[哪个更快?]在利伯特的博客上。我认为Ersönmez先生的答案是最正确的。
我试图提到一些我们应该记住的高级编程语言。
首先,我从未听说过条件运算符应该比c#中的if-else语句更快或性能相同。
原因很简单,如果没有if-else语句的操作:
if (i > 0)
{
value += 2;
}
else
{
}
条件操作符的要求是:必须有一个值的任意边,并且在c#中,它还要求:的两端具有相同的类型。这只是使它不同于if-else语句。因此,你的问题变成了问指令的机器代码是如何产生的,从而导致性能的差异。
如果使用条件操作符,从语义上讲它是:
无论表达式的值是多少,都有一个值。
但是使用if-else语句:
如果表达式被赋值为true,执行一些操作;如果没有,做另一件事。
if-else语句不一定包含值。你的假设只有在优化时才有可能。
另一个例子可以说明它们之间的区别,如下所示:
var array1=new[] { 1, 2, 3 };
var array2=new[] { 5, 6, 7 };
if(i>0)
array1[1]=4;
else
array2[2]=4;
上面的代码编译,但是,用条件操作符替换if-else语句不会编译:
var array1=new[] { 1, 2, 3 };
var array2=new[] { 5, 6, 7 };
(i>0?array1[1]:array2[2])=4; // incorrect usage
当你做同样的事情时,条件操作符和if-else语句在概念上是相同的,在C中使用条件操作符可能更快,因为C更接近平台的程序集。
对于您提供的原始代码,条件操作符在foreach循环中使用,这将使查看它们之间的区别变得混乱。所以我提议以下代码:
public static class TestClass {
public static void TestConditionalOperator(int i) {
long value=0;
value+=i>0?2:3;
}
public static void TestIfElse(int i) {
long value=0;
if(i>0) {
value+=2;
}
else {
value+=3;
}
}
public static void TestMethod() {
TestConditionalOperator(0);
TestIfElse(0);
}
}
以下是优化和未优化的IL的两个版本。因为它们很长,我用一张图片来展示,右边是优化后的:
(点击查看全尺寸图片。)
在这两个版本的代码中,条件操作符的IL看起来都比if-else语句短,并且最终生成的机器代码仍然存在疑问。以下是两种方法的说明,前者为未优化图像,后者为优化图像:
非优化说明:(点击查看全尺寸图片)
优化说明:(点击查看全尺寸图片)
在后者中,黄色块是仅当i<=0时执行的代码,蓝色块是当i>0时执行的代码。在任何版本的指令中,if-else语句都较短。
请注意,对于不同的指令,[CPI]不一定相同。逻辑上,对于相同的指令,更多的指令需要更长的周期。但是如果将指令获取时间和管道/缓存也考虑在内,那么实际的总执行时间取决于处理器。处理器还可以预测分支。
现代处理器甚至有更多的核心,事情可能会更复杂。如果你是英特尔处理器的用户,你可能想看一下[英特尔®64和IA-32架构优化参考手册]。
我不知道是否有硬件实现的CLR,但如果有,使用条件操作符可能会更快,因为IL明显更少。
注:所有机器代码都是x86的。