2010-08-06 47 views
1

另一個「不重要」的性能問題。 不重要的,因爲主要代碼可讀性比幾毫秒更重要,但無論如何有趣。 我注意到不同DateTime比較之間存在差異。爲什麼Date1.CompareTo(Date2)> 0比Date1> Date2更快?

我檢查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 = 毫秒
  2. Date.Compare( Date1,Date2)> 0 = 13510/13194/13081/13353/13092 = ms
  3. Date1.CompareTo(Date2)> 0 = 11776/11768/11865/11776/11847 = 毫秒

通常我選擇第一方法,因爲它是更具有可讀性和比其他故障安全。方法3是最快的。這是編譯器在我使用運算符重載方法1時會選擇的方法嗎?如果是,爲什麼在運行時會有差異? 方法2是最慢的,也許是因爲它是共享/靜態的?! UPDATE:增加了一些更多的值。現在Metod 1和2相當快。

也許有人可以用事實來澄清它。 謝謝。

+2

在10億次迭代中,相差不到2秒......實際上並不重要,也不重要。 – Oded 2010-08-06 10:44:36

+1

您是否測量過多次,排除異常值並對結果進行平均? – 2010-08-06 10:45:09

+0

無論原因如何,「緩慢」版本每秒(在您的硬件上)的* 75百萬*比較而不是* 85百萬*。除非您在某個問題的基準測試中依賴於性能的應用程序處於緊縮環境中,否則更偏好於微觀優化的可讀性。 – 2010-08-06 10:57:20

回答

2

讓我們用一些反射魔法這個功能(全部來自日期時間型):

操作 「>」

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

讓我們來分析一下:

操作>

  • 兩名反對私有財產
  • 每次調用發出一個演員和一個二進制通話And

Compare和CompareT Ø

  • 創建兩個變量,並對它們進行比較

CompareTo是最有可能更快,因爲它不需要訪問outside對象,而是可以借鑑本身的變量之一。

編輯:從看功能我意識到,>性能應該始終保持不變,而CompareCompareTo性能的基礎上傳遞的值:

  • T1更大:最快
  • T2更大:中
  • T1 T2 ==:最慢

雖然,我們談論的績效增益或損失是......我該怎麼說...我無所謂。 ;)但是這很安靜有趣,我同意。

+3

DateTime是一個結構體,因此通過值(複製)傳遞給方法調用。這會使CompareTo的堆棧幀比其他堆棧幀小。有趣的是,Compare和CompareTo都使用對隨機數據執行(略微)更差的分支操作(測試數據總是遵循CPU將優化的同一分支)。我沒有嘗試過,但我希望操作符<對隨機輸入更快。 – star 2010-08-06 12:18:36

+0

@star:你的評論應該是一個答案,值得自己投票。 – 2010-08-07 16:02:22

0

如果數字持續存在,可能會有某種緩存在進行。爲了檢測這個,你可以嘗試在你的程序中重新排序測試或重複測試三元組(如ABCABC)。

+0

重新排序時,似乎沒有什麼區別 – 2010-08-06 11:14:11

相關問題