views:

88

answers:

2

Another "unimportant" performance question. Unimportant because mostly code-readability is much more important than a few milliseconds, but interesting anyway. I noticed that there are differences between different DateTime Comparisons.

I checked 3 alternatives:

    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

The results:

  1. Date1 > Date2 = 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

Normally i choose first method because it is more readable and fail-safer than the others. Method 3 is the fastest. Is this the method that the compiler would choose when i use the operator overloaded method 1? When yes, why are there differences during runtime? Method 2 is the slowest, maybe because it is shared/static?! UPDATE: added some more values. Now Metod 1 and 2 are pretty equal fast.

Perhaps somebody could clarify it with facts. Thanks.

A: 

If the numbers persist, there could be some kind of caching going on. To detect this you could try to reorder the tests in you program or repeat the test triplet (like ABCABC).

Peter G.
There seems to be no difference when reordering
Tim Schmelter
+2  A: 

Let's use some Reflector-Magic on this functions (all from the DateTime-Type):

Operator " > "

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

Compare

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

Let's break it down:

Operator >

  • Two calls against a private property
  • Each call issues one cast and one binary And

Compare and CompareTo

  • Creates two variables and compares them

CompareTo is most likely faster because it does not need to access an outside object, but can instead draw one of the variables from itself.

Edit: From looking at the functions I realize that the performance of > should always stay the same, while the performance of Compare and CompareTo are based on the passed values:

  • t1 is greater: fastest
  • t2 is greater: middle
  • t1 == t2: slowest

Though, the performance gain or loss we're talking about is...how shall I say...I couldn't care less. ;) But it's quiet interesting, I agree.

Bobby
DateTime is a struct and therefore passed by value (copied) into method calls. This would make the stack frame for CompareTo smaller than the others. Interestingly though, Compare and CompareTo both use branch operations which would perform (slightly) worse against random data (the test data always follows the same branch which the CPU will optimize for). I haven't tried it, but I would expect operator< to be faster against random input.
star
@star: Your comment should be an answer, and deserves votes of its own.
P Daddy