c#中的哪个更快
int a = 10;
bool _IsEven;
if(a%2 == 0)
{
_IsEven = true;
}
else
{
_IsEven = false;
}
或者
int a = 10;
bool _IsEven = a%2 == 0 ? true : false;
更新
我知道我可以在编写
时优化我的代码bool _IsEven = a%2 == 0;
但我的问题不是关于代码优化,而是关于 这两个语句的表现 ???
你能帮助我提高我的编码知识吗?
答案 0 :(得分:6)
你的第二个代码甚至不会编译。但你可以写:
bool isEven = a % 2 == 0;
或
bool isEven = (a & 1) == 0;
为什么使用 条件运算符或 if
语句?
一般来说,当你有类似的东西时:
if (condition)
{
x = true;
}
else
{
x = false;
}
或
x = condition ? true : false;
你可以写:
x = condition;
我认为C#编译器无论如何都会对此进行优化,我不会感到惊讶,但我不会像可读性那样关注性能。
答案 1 :(得分:3)
根据此benchmark comparison,if..else
块的运行速度与?..:
三元运行一样快,与单级切换/案例语句一样快。
因此,在我看来,为了获得更好的可读性和更清晰的陈述而不是担心性能会更好,因为它对你的情况影响很小。
答案 2 :(得分:0)
编辑:如果没有其他内容,请阅读底部的结论。休息试图向一般读者说明为什么结论有意义。
请注意,我对这个问题的直接反应是,这不重要。而且,对于大多数实际目的,你不应该发现任何差异......任何人甚至可能会争辩说,他们只是两种不同的方式来实现相同的事情 ...虽然可读性当然可能是不同,取决于编写这些语句所涉及的实际三个表达式。即。
true
false
最重要的是,正如其他人所建议的那样,你应该能够通过(我假设发布版本)来解决这个问题。
但是假设你因为好或坏的原因而对微观优化感兴趣,我也很好奇并且自己看了看......纯粹是为了我的娱乐,这就是我找到的 -
注意:以下结果必须不视为绝对,因为
.Net 4.5
,Release
构建。<强>代码强>
int a = 1;
int b = 2;
int h = 0;
h = a == b ? 10 : -10;
GC.KeepAlive(h);
h = a == b ? 10 : -10;
的IL
IL_0006: ldloc.0
IL_0007: ldloc.1
IL_0008: beq.s IL_000e
IL_000a: ldc.i4.s -10
IL_000c: br.s IL_0010
IL_000e: ldc.i4.s 10
IL_0010: stloc.2
h = a == b ? 10 : -10;
的汇编
00482B61 mov eax,dword ptr [ebp-8]
00482B64 cmp eax,dword ptr [ebp-0Ch]
00482B67 je 00482B73
00482B69 nop
00482B6A mov dword ptr [ebp-14h],0FFFFFFF6h
00482B71 jmp 00482B7A
00482B73 mov dword ptr [ebp-14h],0Ah
00482B7A mov eax,dword ptr [ebp-14h] <-- Extra compared to 2nd experiment
00482B7D mov dword ptr [ebp-10h],eax <-- Extra compared to 2nd experiment
<强>代码强>
int a = 1;
int b = 2;
int h = 0;
if (a == b) h = 10; else h = -10;
GC.KeepAlive(h);
if (a == b) h = 10; else h = -10;
的IL
IL_0006: ldloc.0
IL_0007: ldloc.1
IL_0008: bne.un.s IL_000f
IL_000a: ldc.i4.s 10
IL_000c: stloc.2 <-- Extra compared to 1st experiment
IL_000d: br.s IL_0012
IL_000f: ldc.i4.s -10
IL_0011: stloc.2
if (a == b) h = 10; else h = -10;
的汇编
0086288E mov eax,dword ptr [ebp-8]
00862891 cmp eax,dword ptr [ebp-0Ch]
00862894 jne 008628A0
00862896 mov dword ptr [ebp-10h],0Ah
0086289D nop
0086289E jmp 008628A7
008628A0 mov dword ptr [ebp-10h],0FFFFFFF6h
我再说一遍,不是来自C#或JIT编译器团队,这个分析只是我的猜测(我可能犯了错误,错误的假设),而且很可能是实现细节< / strong>,将来可能会发生变化。最后,但并非最不重要的是,优化可能很好地受到其他几个因素/变化 的影响。
基于IL:
为实验1 生成的IL看起来更好,从某种意义上说,虽然最终结果显然是相同的,但编译器确实已经生成了1条额外的IL指令实验2 。即if
块和else
块的每个表达式,似乎都是独立处理的,因此,当您和我知道代码涉及赋值变量h
时,编译器会处理这两个代码块是单独的,如果使用h
,则生成用于分配给if..else..
的独立代码。
IL_000c: stloc.2 <-- Extra compared to 1st experiment
....
IL_0011: stloc.2
因此,使用?:
运算符,似乎会生成较小的 IL ,因此可能会有更好的代码..(小代码可以也更快,因为那里在CPU的执行缓存中加载的指令较少,因此根据其他条件执行速度较快的机会很小。但是,请注意这是不机器代码。)
稍后,实验1 应该优于实验2 ,被证明 不正确 ,基于由 JIT编译器生成的汇编代码。 (只是为了证明,虽然IL优化有其地位..最后,重要的是由 JIT编译器生成的代码)。
基于程序集(计数器直观):
事实证明,当橡胶碰到道路时,即装配时,实验1 的指令比实验2 强两个,并且应该运行得更慢(在微观层面)。这是我的猜测为什么 -
IL_0008: beq.s IL_000e
IL_000a: ldc.i4.s -10
IL_000c: br.s IL_0010
IL_000e: ldc.i4.s 10
IL_0010: stloc.2
00482B6A mov dword ptr [ebp-14h],0FFFFFFF6h <-- IL_000a: ldc.i4.s -10
00482B73 mov dword ptr [ebp-14h],0Ah <-- IL_000e: ldc.i4.s 10
00482B7A mov eax,dword ptr [ebp-14h] <-- IL_0010: stloc.2
00482B7D mov dword ptr [ebp-10h],eax <-- IL_0010: stloc.2
dword ptr [ebp-14h]
显然是一个临时变量,它存储表达式#2 (条件为true
)或上面的表达式#3 (条件是false
)..(行为可能完全根据表达式本身而变化..我不知道)..然后必须移动值从临时变量到CPU寄存器的值,然后从CPU寄存器到堆栈上为局部变量h
分配的位置。
IL_0008: bne.un.s IL_000f
IL_000a: ldc.i4.s 10
IL_000c: stloc.2
IL_000d: br.s IL_0012
IL_000f: ldc.i4.s -10
IL_0011: stloc.2
00862896 mov dword ptr [ebp-10h],0Ah <-- IL_000a: ldc.i4.s 10
<-- IL_000c: stloc.2
008628A0 mov dword ptr [ebp-10h],0FFFFFFF6h <-- IL_000f: ldc.i4.s -10
<-- IL_0011: stloc.2
这里很清楚,值10
需要加载到堆栈上的潜在临时变量,然后立即从该位置移动到位置堆栈上的变量h
。我想,通过将两个加载和商店说明紧挨着彼此,对于 JITter来说应该很容易认为它可以直接将值存储到局部变量中,没有需要临时变量。因此, 看似 未优化的IL代码应该在生成汇编代码 JITter 时表现更好。
虽然我个人的选择是在晚上花时间写下这个长篇答案,但感谢所有读完这篇文章以达到我最终结论的人。
微优化不仅可以通过更高的语言级别构造而且可以因各种其他因素(可能不在您的控制中)而变化。我猜测,3个表达式中的代码将 as非常重要您选择if..else..
vs ?:
,以及所使用的编译器和运行时版本,以及操作系统上的其他条件。
因此,假设微优化对您来说非常重要,除非您已准备好运行性能测试,针对您的特定代码(忽略另一个答案中提供的基准测试。在许多情况下,运行自己的测试进行此类微优化本身就很难,因为它们很容易受到外部系统因素影响,如OS Scheduler等),您在此代码中每次更改/每次运行时版本更改(要检查效果回归),您遇到的问题毫无意义,而且您的问题有否绝对答案。
< / LI> 醇>PS - 我希望,这个答案成为Stack Overflow上这类(通用微优化/性能)问题的一个很好的例子,几乎每天都会遇到这样的问题:(。