C# <;=和>;=在浮点类型上使用时
我听说当使用C# <;=和>;=在浮点类型上使用时,c#,performance,operators,C#,Performance,Operators,我听说当使用=操作符时,编译器会自动优化它:(int)Variable>=2变成(int)Variable>1。对于浮点类型,这是真的吗?在我看来,(float)Variable>=2无法优化为(float)Variable>1.99999999,否则会导致无限大,要么导致不可能,要么影响性能。(我知道性能上的差异可能很小,但这正是我想知道的)如果您检查生成的IL代码,这不是真的。例如,考虑下面的类: public class C { public void M() {
=
操作符时,编译器会自动优化它:(int)Variable>=2
变成(int)Variable>1
。对于浮点类型,这是真的吗?在我看来,(float)Variable>=2
无法优化为(float)Variable>1.99999999
,否则会导致无限大,要么导致不可能,要么影响性能。(我知道性能上的差异可能很小,但这正是我想知道的)如果您检查生成的IL代码,这不是真的。例如,考虑下面的类:
public class C
{
public void M()
{
float a = 4;
float b = 5;
bool result = a >= b;
}
}
生成的IL代码如下所示:
.class public auto ansi beforefieldinit C
extends [mscorlib]System.Object
{
// Methods
.method public hidebysig
instance void M () cil managed
{
// Method begins at RVA 0x2050
// Code size 22 (0x16)
.maxstack 2
.locals init (
[0] float32,
[1] float32,
[2] bool
)
IL_0000: nop
IL_0001: ldc.r4 4
IL_0006: stloc.0
IL_0007: ldc.r4 5
IL_000c: stloc.1
IL_000d: ldloc.0
IL_000e: ldloc.1
IL_000f: clt.un
IL_0011: ldc.i4.0
IL_0012: ceq
IL_0014: stloc.2
IL_0015: ret
} // end of method C::M
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x2072
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method C::.ctor
} // end of class C
如果您阅读了上面生成的IL代码(用作IL命令的参考),您会注意到这不是真的
简而言之,在上面的IL代码中,float
数字被加载到堆栈中,然后使用clt.un
操作,该操作:
如果value1小于value2,无符号或无序,则按1键(int32类型),否则按0键
然后,使用ceq
,将此操作的结果与0进行相等性比较,其中:
如果value1等于value2,则按1(int32类型),否则按0
并将上述结果分配给结果
变量
对于所有这些JNE
如果不相等则跳转,JE
如果相等则跳转,JG
如果较大则跳转,JLE
如果小于或等于则跳转,JL
如果大于或等于则跳转。然而,如果这些变量被装箱,您最大的性能损失将是。事实上,如果你有一个性能问题,为什么不使用一个基准测试,并为自己测试这些东西呢?