[英]Can the C# compiler optimize this cast away?
I'm doing the following cast to double
and back to long
, intentionally: 我正在执行以下转换以故意
double
并返回long
:
var adjustedValue = (long)(double)dateTime.Ticks;
(where dateTime
is a System.DateTime
and Ticks
is a long
). (其中
dateTime
是System.DateTime
而Ticks
是long
)。 Resharper tells me however that the cast to double
is "redundant" and this has me wondering if it can be optimized away by the compiler. Resharper告诉我,转换为
double
是“冗余的”,这让我想知道编译器是否可以对其进行优化。
I tried out this code in LINQPad : 我在LINQPad中尝试了以下代码:
var dateTime = DateTime.Now;
var adjustedValue = (long)(double)dateTime.Ticks;
adjustedValue.Dump();
Both with and without optimizations, it generated identical IL (the only difference being in the labels): 无论是否进行优化,它都会生成相同的IL(唯一的区别在于标签):
IL_0000: call System.DateTime.get_Now
IL_0005: stloc.0 // dateTime
IL_0006: ldloca.s 00 // dateTime
IL_0008: call System.DateTime.get_Ticks
IL_000D: conv.r8
IL_000E: conv.i8
IL_000F: stloc.1 // adjustedValue
IL_0010: ldloc.1 // adjustedValue
IL_0011: call LINQPad.Extensions.Dump
So the answer is no , the C# compiler does not optimize this double cast. 因此答案是“ 否” ,C#编译器不会优化这种双重转换。 The conversions are there, even when optimizations are turned on.
即使启用了优化,转换也在那里。
However, you should also notice that this double-cast does significantly change the original data. 但是,您还应该注意,此双重广播确实会极大地更改原始数据。 Here's a quick demo, also created using LINQPad:
这是一个快速演示,也是使用LINQPad创建的:
var dateTime = DateTime.Now;
var originalValue = dateTime.Ticks;
var adjustedValue = (long)(double)originalValue;
originalValue.Dump(); // 635385353415288655
adjustedValue.Dump(); // 635385353415288704
This is because a double
only has 15-16 digits of precision, but a long
may be up to 19 digits long. 这是因为
double
精度只具有15到16位的精度,但long
可能长达19位。 You're bound to get some amount of rounding error. 您一定会遇到一些舍入误差。 If this is a problem, you could use a
decimal
instead. 如果这是一个问题,则可以改用
decimal
。 This will avoid any rounding errors, but even in this case, the double-cast will not be optimized away by the C# compiler. 这样可以避免任何舍入错误,但是即使在这种情况下,C#编译器也不会优化双播。
Of course, how the JIT compiler or NGen.exe convert this to native code is an entirely different matter, but I would expect the behavior to be the same. 当然,JIT编译器或NGen.exe如何将其转换为本地代码是完全不同的事情,但是我希望其行为是相同的。
I just checked it out. 我刚刚检查了一下。 With "dotPeek 1.1" I "took a look" into the source code of this.
使用“ dotPeek 1.1”,我可以“看一下”它的源代码。
With configuration Debug it keeps as is, because the /optimize flag is not set. 使用Debug配置时,它会保持原样,因为未设置/ optimize标志。 With configuration Release there is indeed something changed, but not the casts.
通过配置Release,确实确实发生了一些变化,但类型没有变化。 In Release, as default, /optimize switch is turned on.
在发行版中,默认情况下,/ optimize开关处于打开状态。
var adjustedValue = (long)(double)DateTime.Now.Ticks;
Console.WriteLine(adjustedValue);
went to 去了
Console.WriteLine((long) (double) DateTime.Now.Ticks);
Résumé: 恢复:
It will not optimize this way of cast. 它不会优化这种投射方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.