C# 否则哪个更快?:
c语言中哪个更快C# 否则哪个更快?:,c#,performance,if-statement,C#,Performance,If Statement,c语言中哪个更快 int a = 10; bool _IsEven; if(a%2 == 0) { _IsEven = true; } else { _IsEven = false; } 或 更新 我知道在这里我可以优化我的代码,只需编写 bool _IsEven = a%2 == 0; 但我的问题不是关于代码优化,而是关于这两条语句的性能 你能帮我提高我的编码知识吗?你的第二个代码甚至无法编译。但你可以写: bool isEven = a % 2 == 0; x = cond
int a = 10;
bool _IsEven;
if(a%2 == 0)
{
_IsEven = true;
}
else
{
_IsEven = false;
}
或
更新
我知道在这里我可以优化我的代码,只需编写
bool _IsEven = a%2 == 0;
但我的问题不是关于代码优化,而是关于这两条语句的性能
你能帮我提高我的编码知识吗?你的第二个代码甚至无法编译。但你可以写:
bool isEven = a % 2 == 0;
x = condition;
或
为什么要使用条件运算符或if语句
通常,当您有以下情况时:
if (condition)
{
x = true;
}
else
{
x = false;
}
或
你可以写:
bool isEven = a % 2 == 0;
x = condition;
无论如何,看到C编译器优化这一点我都不会感到惊讶,但我不会像关注可读性那样关注性能。根据这一点,if..else块的运行速度与?:三元运算的运行速度一样快,与单级switch/case语句的运行速度一样快
因此,在我看来,与其担心性能,不如追求更好的可读性和更清晰的陈述,因为它对您的情况影响最小。编辑:如果没有其他内容,请阅读底部的结论。Rest试图向普通读者解释为什么结论是有意义的
请注意,我对这个问题的直接反应是,这不重要。从最实际的角度来看,你不应该发现任何不同。。。任何人都可能会说,它们只是实现同一目标的两种不同方式。。。尽管可读性当然可能有所不同,但这取决于编写这些语句所涉及的实际三种表达方式。i、 e
条件表达式
表达式,如果条件为true
表达式,如果条件为false
最重要的是,正如其他人所建议的,您应该能够通过我假设的发布版本来理解这一点
查看生成的IL。
使用大量迭代对代码进行计时。
但是,假设你对微优化感兴趣,不管原因是好是坏,我也很好奇,自己也看了看。。纯粹是为了消遣,这就是我发现的-
注:以下调查结果不得视为绝对结果,因为
它们可能取决于几个我不知道的因素,包括我在测试中选择的上面提到的3个表达式。
任何人都会争辩说,即使所有因素都已知,其中许多都是C编译器或JIT编译器的内部细节,因此可以随任一编译器的任何版本而改变。我在我的机器上做了一个奇怪的小实验。NET4.5,发布版本。
实验1
代码
h=a=b的IL?10 : -10;
h=a=b的装配?10 : -10;
如果a==bh=10,则为IL;否则h=-10
分析
我重复一遍,不是来自C或JIT编译器团队,这一分析只是我的猜测,我可能已经犯了错误,错误的假设,并且很可能,作为实现细节,在未来的版本中可能会发生更改。最后,但并非最不重要的一点是,优化很可能是由这里根本没有考虑的几个其他因素/变化驱动的
基于IL:
为实验1生成的IL看起来更好,因为虽然最终结果明显相同,但编译器似乎确实为实验2生成了1条额外的IL指令。i、 e.if块和else块的每个表达式似乎都被视为独立的,因此,虽然您和我都知道代码涉及到对变量h的赋值,但编译器将这两个代码块视为单独的,并生成独立代码以赋值给h if..else。。使用
dword ptr[ebp-14h]显然是一个临时变量,它存储上述表达式2条件为真或表达式3条件为假的结果。。行为可能完全因表达式本身而异。。我不知道。。然后必须将值从临时变量移到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代码在生成汇编代码抖动时应该表现得更好
结论
虽然这是我个人的选择,花我的时间在晚上写这一长的答案,任何人谁读了通过这一点,以达到我的最终结论,我的荣誉
微观优化不仅会因更高的语言级别结构而有所不同,还会因各种其他因素而有所不同,这些因素可能不在您的控制范围之内。。我猜,3个表达式中的代码与您选择的if..else..一样重要。。vs?:,以及com的版本
使用了piler和runtime,以及操作系统上的其他条件
因此,假设微优化对您来说非常重要,除非您已经准备好运行性能测试,因为您的特定代码忽略了另一个答案中提供的基准测试。。在许多情况下,为这些微优化运行您自己的测试本身可能非常困难,因为它们很容易受到外部的、系统范围的因素的影响,如OS Scheduler等。随着您在该代码中所做的每一次更改/每次运行时版本更改以检查性能退化,您遇到的问题毫无意义,你的问题没有绝对的答案
PS-我希望,这个答案能成为关于堆栈溢出的此类通用微优化/性能问题的一个很好的例子,几乎每天都会遇到:。将每个问题放入一个循环中,并测量运行它们100万次所需的时间。看看生成的IL,看看它们之间的区别。嘿,Nadeem_MK,这只是我解释问题的一个例子。如果他们有很多条件需要检查呢???那么一切都取决于条件。要进行验证,可以做的一件事是将条件放入循环中,并记录执行时间。
int a = 1;
int b = 2;
int h = 0;
h = a == b ? 10 : -10;
GC.KeepAlive(h);
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
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);
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
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
IL_000c: stloc.2 <-- Extra compared to 1st experiment
....
IL_0011: stloc.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
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