naw*_*fal 7 c# performance boxing casting nullable
我做了一些基准测试时遇到了这个问题.
bool b;
MyStruct s;
for (int i = 0; i < 10000000; i++)
{
b = (object)s == null;
}
Run Code Online (Sandbox Code Playgroud)
调试:200毫秒
发布:5毫秒
bool b;
MyStruct? s = null;
for (int i = 0; i < 10000000; i++)
{
b = (object)s == null;
}
Run Code Online (Sandbox Code Playgroud)
调试:800毫秒
发布:800毫秒
我可以理解这个结果,因为转换可为空的结构给object了我一个盒装类型的结构.但是为什么不进行转换struct s以object进行空比较(如在第一种方法中)导致相同的性能?编译器是否正在优化调用以返回,false因为结构不能为null?
是的,编译器正在优化它.
它知道struct永远不能为null,因此将它转换为对象的结果永远不会为null - 因此它将b在第一个示例中设置为false.事实上,如果你使用Resharper,它会警告你表达式总是假的.
对于第二个当然,可以为空的null可以为空,因此必须进行检查.
(您还可以使用Reflector检查编译器生成的IL代码来验证这一点.)
原始测试代码并不好,因为编译器知道可空结构将始终为null,因此也会优化掉该循环.不仅如此,在发布版本中,编译器实现了b未使用的优化并优化了整个循环.
为了防止这种情况,并显示更真实的代码会发生什么,请测试它:
using System;
using System.Diagnostics;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
bool b = true;
MyStruct? s1 = getNullableStruct();
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
b &= (object)s1 == null; // Note: Redundant cast to object.
}
Console.WriteLine(sw.Elapsed);
MyStruct s2 = getStruct();
sw.Restart();
for (int i = 0; i < 10000000; i++)
{
b &= (object)s2 == null;
}
Console.WriteLine(sw.Elapsed);
}
private static MyStruct? getNullableStruct()
{
return null;
}
private static MyStruct getStruct()
{
return new MyStruct();
}
}
public struct MyStruct {}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1782 次 |
| 最近记录: |