【问题标题】:Are implicit casting and explicit casting has the same performance?隐式转换和显式转换是否具有相同的性能?
【发布时间】:2020-02-18 06:38:02
【问题描述】:

以 w3school 为例:

int myInt = 9;
double myDouble = myInt;       // Automatic casting: int to double

Console.WriteLine(myInt);      // Outputs 9
Console.WriteLine(myDouble);   // Outputs 9

double myDouble = 9.78;
int myInt = (int) myDouble;    // Manual casting: double to int

Console.WriteLine(myDouble);   // Outputs 9.78
Console.WriteLine(myInt);      // Outputs 9

显式转换是否会增加额外的开销,尤其是对于大量数字/数组?还是和隐式转换一样?

出于学术原因,我不得不问这个问题,并且还想在任何地方显式地转换我的对象和接口以增加代码库的清晰度。

编辑

添加动物示例:

IAnimal animal = (IAnimal) dog;
IAnimal animal = dog;

【问题讨论】:

  • 隐式与显式是语法上的区别。不管怎样,它正在发生;它生成的 IL 是相同的。处理方面没有区别,两者之间没有额外的开销。
  • 如果您在代码中可以进行隐式强制转换的地方放置显式强制转换,Visual Studio 2019 将调暗强制转换并为您提供代码修复以删除不必要的强制转换。隐式转换可以让您的生活更轻松。
  • 我明白了,所以它更像是语法糖,那么接口呢?它仍然在 IL 上生成相同的代码吗?例如上面的动物
  • 是的。如果转换是隐式的,不管是接口还是基类,都是一样的。当一个值类型被隐式转换为接口时,它必须首先装箱该值,无论它是隐式转换还是显式转换。与用户定义的隐式转换操作符相同,它仍然需要调用操作符的op_Implicit 方法。
  • 你做错了。通过学习十亿个单独的规则并始终应用它们,您不会获得性能良好的代码。 您需要性能良好的代码时,您可以设定目标,编写满足要求的简单代码,然后根据目标衡量代码。只有当它不符合目标时,您才会开始深入研究为什么它表现不佳,然后您实际上可以尝试替代方案并查看 a) 是否有所作为,b) 是否有所不同重要到足以让它现在通过目标。

标签: c# interface casting


【解决方案1】:

显式转换是否会增加额外的开销,尤其是对于大量数字/数组?还是和隐式转换一样?

您可以参考SharpLab 以了解 IL 引擎盖下的差异。如您所见,逻辑几乎相同(当然类型除外,因为您使用的是不同的类型)

.method public hidebysig 
instance float64 AutoCast () cil managed 
{
    .maxstack 8

    IL_0000: ldc.i4.s 9
    IL_0002: conv.r8
    IL_0003: ret
} // end of method C::AutoCast

.method public hidebysig 
instance int32 ManualCast () cil managed 
{
    .maxstack 8

    IL_0000: ldc.r8 9.78
    IL_0009: conv.i4
    IL_000a: ret
} // end of method C::ManualCast

甚至可以参考 ASM 代码

C.AutoCast()
    L0000: sub esp, 0x8
    L0003: vzeroupper
    L0006: vmovsd xmm0, qword [0x14540488]
    L000e: vmovsd [esp], xmm0
    L0013: fld qword [esp]
    L0016: add esp, 0x8
    L0019: ret

C.ManualCast()
    L0000: mov eax, 0x9
    L0005: ret

如您所见,将double 转换为int 只是移动值并返回一个整数部分,intdouble 更复杂。因此,您可以看到不同的基准测试结果。

当然,这取决于使用的 CLR 和 .NET 版本(.NET Core 有很多改进,还添加了一些硬件内在函数)。我使用 .NET Core 和 CoreCLR 运行它,在 .NET Framework 中您会看到不同的结果。

您可以使用代码检查环境中的确切行为(至少因为您出于学术原因提出了问题)

【讨论】:

  • 谢谢 Pavel 先生,看来如果没有 SharpLab,我将无法得到准确的答案。对不起 Pavel 先生,这是否意味着我的问题标题,您的答案是肯定的(相同)?
  • 例如,从 double 转换为 int 反之亦然,答案似乎是“否”,因为实际上存在一些差异(取决于使用的 .NET 版本等)。对于其他情况,答案“取决于”:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-15
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 2012-03-22
相关资源
最近更新 更多