Почему Date1.CompareTo (Date2)> 0 быстрее, чем Date1> Date2? - PullRequest
1 голос
/ 06 августа 2010

Еще один «неважный» вопрос производительности. Неважно, потому что в основном читабельность кода гораздо важнее, чем несколько миллисекунд, но в любом случае интересна. Я заметил, что есть различия между различными сравнениями DateTime.

Я проверил 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 мс
  2. Дата. Сравнение (Дата1, Дата2)> 0 = 13510/13194/13081/13353/13092 = 13246 мс
  3. Date1.CompareTo (Date2)> 0 = 11776/11768/11865/11776/11847 = 11806 мс

Обычно я выбираю первый метод, потому что он более читабелен и безопасен, чем другие. Метод 3 самый быстрый. Это метод, который компилятор выберет, когда я использую метод перегруженного оператора 1? Когда да, почему существуют различия во время выполнения? Метод 2 самый медленный, может быть потому, что он общий / статический ?! ОБНОВЛЕНИЕ : добавлено еще несколько значений. Теперь Методы 1 и 2 довольно быстрые.

Возможно, кто-то мог бы объяснить это фактами. Спасибо.

Ответы [ 2 ]

2 голосов
/ 06 августа 2010

Давайте используем некоторые 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;
}

Давайте разберем это:

Оператор>

  • Два вызова против частной собственности
  • Каждый вызов выполняет один бросок и один двоичный файл And

Compare and CompareTo

  • Создает две переменные и сравнивает их

CompareTo, скорее всего, быстрее, поскольку ему не требуется доступ к объекту outside, но вместо этого он может нарисовать одну из переменных изсама.

Редактировать: Из анализа функций я понимаю, что производительность > всегда должна оставаться неизменной, в то время как производительность Compare и CompareTo основана напереданные значения:

  • t1 больше: самый быстрый
  • t2 больше: средний
  • t1 == t2: самый медленный

Хоть,выигрыш или потеря производительности, о которых мы говорим, это ... как бы сказать ... мне наплевать.;) Но это тихо интересно, я согласен.

0 голосов
/ 06 августа 2010

Если числа сохраняются, возможно, происходит какое-то кэширование. Чтобы обнаружить это, вы можете попытаться изменить порядок тестов в вашей программе или повторить триплет (например, ABCABC).

...