为什么Date1.CompareTo(Date2)>比Date1>快0 DATE2?

时间:2010-08-06 10:42:07

标签: .net vb.net performance comparison operator-overloading

另一个“不重要”的表现问题。 不重要因为大多数代码可读性比几毫秒重要​​得多,但无论如何都很有趣。 我注意到不同的DateTime Comparisons之间存在差异。

我检查了3个替代方案:

    Dim clock As New System.Diagnostics.Stopwatch
    Dim t1, t2, t3 As Long
    Dim Date1 As Date = Date.Now.AddSeconds(2), Date2 As Date = Date.Now
    Dim isGreaterThan As Boolean
    clock.Start()
    For i As Int32 = 1 To 1000000000
        isGreaterThan = Date1 > Date2
    Next
    clock.Stop()
    t1 = clock.ElapsedMilliseconds
    clock.Reset()
    clock.Start()
    For i As Int32 = 1 To 1000000000
        isGreaterThan = Date.Compare(Date1, Date2) > 0
    Next
    clock.Stop()
    t2 = clock.ElapsedMilliseconds
    clock.Reset()
    clock.Start()
    For i As Int32 = 1 To 1000000000
        isGreaterThan = Date1.CompareTo(Date2) > 0
    Next
    clock.Stop()
    t3 = clock.ElapsedMilliseconds

结果:

  1. 日期1>日期2 = 13207/13251/13267/13569/13100 = 13279 ms
  2. Date.Compare(Date1,Date2)> 0 = 13510/13194/13081/13353/13092 = 13246 ms
  3. Date1.CompareTo(Date2)> 0 = 11776/11768/11865/11776 / 11847 = 11806 ms
  4. 通常我会选择第一种方法,因为它比其他方法更具可读性且更安全。 方法3是最快的。这是我使用运算符重载方法1时编译器会选择的方法吗?什么时候,为什么在运行时会出现差异? 方法2是最慢的,也许是因为它是共享/静态的?! 更新:添加了更多值。现在Metod 1和2非常相同。

    也许有人可以用事实澄清它。 感谢。

2 个答案:

答案 0 :(得分:2)

让我们在这个函数上使用一些Reflector-Magic(全部来自DateTime-Type):

运营商“>”

public static bool operator >(DateTime t1, DateTime t2)
{
    return (t1.InternalTicks > t2.InternalTicks);
}

private long InternalTicks
{
    get
    {
        return (((long) this.dateData) & 0x3fffffffffffffffL);
    }
}

// this.dateData is a private field

<强>比较

public static int Compare(DateTime t1, DateTime t2)
{
    long internalTicks = t1.InternalTicks;
    long num2 = t2.InternalTicks;
    if (internalTicks > num2)
    {
        return 1;
    }
    if (internalTicks < num2)
    {
        return -1;
    }
    return 0;
}

<强>的CompareTo

public int CompareTo(DateTime value)
{
    long internalTicks = value.InternalTicks;
    long num2 = this.InternalTicks;
    if (num2 > internalTicks)
    {
        return 1;
    }
    if (num2 < internalTicks)
    {
        return -1;
    }
    return 0;
}

让我们分解一下:

运营商&gt;

  • 针对私有财产的两次电话
  • 每次调用都会发出一个强制转换和一个二进制And

比较和比较

  • 创建两个变量并进行比较

CompareTo很可能更快,因为它不需要访问outside对象,而是可以从自身中提取其中一个变量。

修改:通过查看函数,我意识到>的效果应始终保持不变,而CompareCompareTo的效果是基于传递的值:

  • t1更大:最快
  • t2更大:中间
  • t1 == t2:slowest

虽然,我们谈论的表现收益或损失是......我该怎么说......我不在乎。 ;)但这很安静,我同意。

答案 1 :(得分:0)

如果数字仍然存在,可能会有某种缓存。要检测到这一点,您可以尝试重新排序程序中的测试或重复测试三元组(如ABCABC)。