gpt4 book ai didi

c# - TimeSpan的比较好慢

转载 作者:太空宇宙 更新时间:2023-11-03 17:42:51 31 4
gpt4 key购买 nike

最近我遇到了一个奇怪的性能问题。
我需要将周期中的时间间隔与大量迭代进行比较。
我使用 DateTime.TimeOfDay 属性来比较这些间隔。但是,我发现这些比较与 DateTime 比较相比非常慢。因此,我必须创建具有 1 年 1 个月和 1 天的 DateTime 以加快时间间隔比较。
我准备了一个小例子来说明我的意思。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DatesBenchmark
{
class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
DateTime firstDate = DateTime.Now;
DateTime secondDate = DateTime.Now.AddSeconds(5);
for (int i = 0; i < 2000000; i++)
{
var a = firstDate.TimeOfDay > secondDate.TimeOfDay;
//var a = firstDate > secondDate;
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
Console.ReadKey();
}
}
}

在我的笔记本电脑上,我得到了 15 毫秒(如果循环中的第一行被注释)与 176 毫秒(如果循环中的第二行被注释)。

我的问题很简短。为什么?

最佳答案

调用 foo.TimeOfDay 是这样做的:

public TimeSpan TimeOfDay
{
get
{
return new TimeSpan(this.InternalTicks % 864000000000L);
}
}

通过访问 TimeOfDay 2楼 DateTime您正在创建超过 200 万次迭代的实例 400 万个 Timespan实例。然而,这还不是最大的开支。

进一步挖掘,你有:
internal long InternalTicks
{
get
{
return (long)(this.dateData & 4611686018427387903uL);
}
}

因此,您有 400 万次实例化、余数计算、强制转换和 &操作。这些都是便宜的操作(“便宜”当然是一个相对的术语),但是它们加起来的数量。

实际比较是微不足道的:
public static bool operator >(TimeSpan t1, TimeSpan t2)
{
return t1._ticks > t2._ticks;
}

在 Debug模式下编译 OPs 代码,我看到:
  • 空循环:4ms。
  • var a = firstDate > secondDate; 6ms(建议没有优化掉)
  • var a = firstDate.TimeOfDay; 40ms
  • var a = firstDate.TimeOfDay > secondDate.TimeOfDay; 80ms
  • TimeSpan a = new TimeSpan( ticks ), b = new TimeSpan( ticks ); 7ms

  • 在 VS 2012 中针对该程序运行性能分析,81% 的样本来自 DateTime.get_TimeOfDay() .

    运行 x64, Release模式,启用所有优化:
  • 空循环:3ms。
  • var a = firstDate > secondDate; 6ms
  • var a = firstDate.TimeOfDay; 20ms
  • var a = firstDate.TimeOfDay > secondDate.TimeOfDay; 40ms
  • TimeSpan a = new TimeSpan( ticks ), b = new TimeSpan( ticks ); 6ms

  • 所以:
  • 微基准可能会产生误导(尽管并非无用)。
  • 在确定存在问题之前启用优化。
  • 性能似乎随着优化而翻倍。
  • 在任何情况下,所讨论的语句似乎都没有被优化掉。
  • 实例化是费用的有形但很小的一部分。
  • 类型转换/算术运算占其余费用。
  • 在循环之前将属性值存储在变量中可以大大提高性能。
  • 关于c# - TimeSpan的比较好慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14653192/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com