代码之家  ›  专栏  ›  技术社区  ›  Tim Schmelter

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

  •  1
  • Tim Schmelter  · 技术社区  · 14 年前

    另一个“不重要”的性能问题。 不重要,因为大部分代码的可读性比几毫秒重要得多,但无论如何都很有趣。 我注意到不同的日期时间比较之间存在差异。

        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
    2. Date.Compare(日期1,日期2)>0 = 13510/13194/13081/13353/13092 = 微软
    3. 日期1.比较(日期2)>0 = 11776/11768/11865/11776/11847 = 微软

    方法三是最快的。当我使用操作符重载的方法1时,编译器会选择这个方法吗?如果是,为什么在运行时会有差异? 方法2是最慢的,可能是因为它是共享/静态的?! 更新

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

    2 回复  |  直到 14 年前
        1
  •  2
  •   Bobby    14 年前

    让我们在此函数上使用一些反射魔法(都来自DateTime类型):

    运算符“>”

    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;
    }
    

    比较

    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;
    }
    

    我们来分解一下:

    操作员>

    • 两起针对私人财产的诉讼
    • 每个调用发出一个cast和一个binary And

    比较

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

    CompareTo 很可能更快,因为它不需要访问 outside 对象,但可以从自身绘制一个变量。

    编辑: > 应始终保持不变,而 Compare 基于传递的值:

    • t1更大:最快
    • t2大于:中间
    • t1==t2:最慢

    不过,我们谈论的绩效得失是……我该怎么说……我一点也不在乎但这很有趣,我同意。

        2
  •  0
  •   Peter G.    14 年前

    如果这些数字持续存在,可能会出现某种缓存。要检测到这一点,可以尝试对程序中的测试重新排序或重复测试三元组(如ABCABC)。