当我分析我的old posts精确解决方案时,我发现了一个矛盾,所以我尝试在Form1构造函数中编写代码(在 InitializeComponent();
之后)
Stopwatch timer = Stopwatch.StartNew();
var timeStartGetStatistic = DateTime.Now.ToString("HH:mm:ss:fff");
var timeEndGetStatistic = DateTime.Now.ToString("HH:mm:ss:fff");
timer.Stop();
Console.WriteLine("Convert take time {0}", timer.Elapsed);
Console.WriteLine("First StopWatch\nStart:\t{0}\nStop:\t{1}",
timeStartGetStatistic, timeEndGetStatistic);
Stopwatch timer2 = Stopwatch.StartNew();
var timeStartGetStatistic2 = DateTime.Now.ToString("HH:mm:ss:fff");
var timeEndGetStatistic2 = DateTime.Now.ToString("HH:mm:ss:fff");
timer2.Stop();
Console.WriteLine("Convert take time {0}", timer2.Elapsed);
Console.WriteLine("Second StopWatch\nStart:\t{0}\nStop:\t{1}",
timeStartGetStatistic2, timeEndGetStatistic2);
结果
转换时间00:00:00.0102284 First StopWatch开始时间:02:42:29:929停止:02:42:29:939转换时间00:00:00.0000069秒秒表开始:02:42:29:940停止: 02:42:29:940
我发现只有 FIRST DateTime.Now.ToString("HH:mm:ss:fff");
消耗 10ms 但 3 others 在同一范围内消耗的数量少于 10us ,我可否知道具体原因?
是因为第一个在内存上创建代码所以后面的3个获得它的优势,消耗更多的时间来做同样的事情?谢谢 .
3 回答
如前所述,你测量错了 . 您不应该包括对任何代码的第一次调用,因为它需要被引用,将包括该时间 .
依靠结果只运行一次也不好;您需要运行代码次数,并且您应该计算平均所用时间 .
确保在未附带调试器的发布模式下执行此操作 .
起初,我认为它确实是JIT ..但它没有意义,因为框架本身是在安装时编译的AOT .
我认为它正在加载当前的文化(
ToString
这样做,事实上它是需要时间的功能)================编辑=============
我做了一些测试,有两件事在他们第一次被调用时需要时间 .
DateTime.Now
调用内部方法TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc
,占用大约一半的消耗时间......其余的被字符串消耗..
如果不是调用
DateTime.Now
而是调用DateTime.UtcNow
,你就不会注意到获得本地时间偏移的第一次影响 .关于
ToString
- 运行时间是什么,为当前文化生成了DateTimeFormat .我认为这很好地回答了你的问题:)
首先从类中调用任何单个方法都需要JIT,因此第一次调用总是很慢(除非使用NGen对程序集进行预处理) .
根据与第一次呼叫相关的方法,加载必要的资源/数据还需要额外的费用 . 即可能
DateTime.Now
和DateTime.ToString
需要加载/预处理某些区域设置数据 .使用秒表测量性能的标准方法是调用您想要测量一次的函数/代码,以完成与代码相关的所有JIT,而不是进行测量 . 通常你会多次运行代码并获得平均结果 .