有时需要使用类型后缀(例如0d表示值为 0 的对偶或0f表示浮点数),并且通常被认为是好的样式。
但它有任何性能影响吗?
所以调用了几百万次
if (x == 0d) ... or
if (x == 0.0) ...
将尽可能快
if (x == 0) ...
我想,编译器会将 0 转换为 0.0 一次,因此性能无关紧要。但由于我在质量代码中看到过几次,我不确定......
由于注释而添加:x 不是 int,而是 double。
有时需要使用类型后缀(例如0d表示值为 0 的对偶或0f表示浮点数),并且通常被认为是好的样式。
但它有任何性能影响吗?
所以调用了几百万次
if (x == 0d) ... or
if (x == 0.0) ...
将尽可能快
if (x == 0) ...
我想,编译器会将 0 转换为 0.0 一次,因此性能无关紧要。但由于我在质量代码中看到过几次,我不确定......
由于注释而添加:x 不是 int,而是 double。
如果您检查 IL 代码,您会在与to 文字conv
比较时发现额外的操作码int
0.0
int x = 0;
Console.WriteLine (x == 0.0);
IL_0000: ldc.i4.0
IL_0001: stloc.0 // x
IL_0002: ldloc.0 // x
IL_0003: conv.r8 //<-- this is absent if literal is 0
IL_0004: ldc.r8 00 00 00 00 00 00 00 00
IL_000D: ceq
IL_000F: call System.Console.WriteLine
这是由于一个事实,Int32
==
运算符重载接受int
作为第二个参数。
备注:使用编译器优化标志在 LINQPad 中编译。
一个重要的说法是在您确定这是一个瓶颈之前不要进行纳米优化。这样的优化通常会破坏代码的可读性和结果 - 可维护性。
在 Ilya Ivanov 的提示下,我检查了一个小示例程序的 IL 代码。
Ilya 假设 x 是一个整数。如果是这种情况,他对转换 (conv.r8) 的评论是绝对正确的。但是我想到的情况是,如果您将 double 类型的变量与 double 文字进行比较。 在这种情况下,类型后缀有什么不同吗?
答案是不!
让我们看看这个小程序,比较 (d == 0) 或 (d == 0d):
static void Main(string[] args)
{
double d = 0.0;
if (d == 0) // if (d == 0d)
d = 1.23;
Console.WriteLine(d);
}
两个版本都编译成完全相同的 IL 代码:
.method private hidebysig static
void Main (
string[] args
) cil managed
{
// Method begins at RVA 0x2050
// Code size 48 (0x30)
.maxstack 2
.entrypoint
.locals init (
[0] float64 d,
[1] bool CS$4$0000
)
IL_0000: nop
IL_0001: ldc.r8 0.0
IL_000a: stloc.0
IL_000b: ldloc.0
IL_000c: ldc.r8 0.0
IL_0015: ceq
IL_0017: ldc.i4.0
IL_0018: ceq
IL_001a: stloc.1
IL_001b: ldloc.1
IL_001c: brtrue.s IL_0028
IL_001e: ldc.r8 1.23
IL_0027: stloc.0
IL_0028: ldloc.0
IL_0029: call void [mscorlib]System.Console::WriteLine(float64)
IL_002e: nop
IL_002f: ret
} // end of method Program::Main
当然,汇编代码也是一样的。
所以写 0 而不是 0.0 或 0d 就好了......