【发布时间】:2017-12-01 10:57:34
【问题描述】:
考虑以下代码:
private static void Main(string[] args)
{
var ar = new double[]
{
100
};
FillTo(ref ar, 5);
Console.WriteLine(string.Join(",", ar.Select(a => a.ToString()).ToArray()));
}
public static void FillTo(ref double[] dd, int N)
{
if (dd.Length >= N)
return;
double[] Old = dd;
double d = double.NaN;
if (Old.Length > 0)
d = Old[0];
dd = new double[N];
for (int i = 0; i < Old.Length; i++)
{
dd[N - Old.Length + i] = Old[i];
}
for (int i = 0; i < N - Old.Length; i++)
dd[i] = d;
}
Debug 模式下的结果是:100,100,100,100,100。 但在发布模式下是:100,100,100,100,0。
发生了什么?
已使用 .NET Framework 4.7.1 和 .NET Core 2.0.0 进行了测试。
【问题讨论】:
-
您使用哪个版本的 Visual Studio(或编译器)?
-
复制;将
Console.WriteLine(i);添加到最终循环 (dd[i] = d;) 中“修复”它,这表明存在编译器错误或 JIT 错误;调查 IL... -
@Styxxy,在 vs2015、2017 上测试并针对每个 .net 框架 >= 4.5
-
绝对是一个错误。如果您删除
if (dd.Length >= N) return;,它也会消失,这可能是一个更简单的复制。 -
毫不奇怪,一旦比较是苹果对苹果,.Net Framework 和 .Net Core 的 x64 代码生成具有相似的性能,因为(默认情况下)它本质上是相同的 jit 生成代码。将 .Net Framework x86 codegen 的性能与 .Net Core 的 x86 codegen(自 2.0 开始使用 RyuJit)进行比较会很有趣。在某些情况下,旧的 jit(又名 Jit32)知道 RyuJit 不知道的一些技巧。如果您发现任何此类情况,请确保在 CoreCLR 存储库上为他们打开问题。