Тест производительности простейших операций: Модуль числа

Всякий раз, когда я пользовался Math.Min() или Math.Abs(), я думал о том, а не лучше было бы написать эти операции простым неравенством.  Наконец, я решил просто написать небольшой тестик, который должен раз и навсегда расставить все на свои места.

В качестве основы я взял почти пустой цикл:

int N = 100000000;

 

Start = DateTime.Now;

//Almost nothing!

for (int i = -N; i < N; i++)              

  result = i;

End = DateTime.Now;

Почти пустой для того чтоб компилятор не сделал каких нить слишком умных действий по его оптимизации. В первую очередь испытанию подверглась функция вычисления модуля числа. Реализовать эту простую операцию можно так:

for (int i = -N; i < N; i++)

{

  result = i;

  result = Math.Abs(i);

}

 

 

или, например, так:

for (int i = -N; i < N; i++)

{

  result = i;

  result = (i >= 0) ? i : -i;

}

 

Из времени выполнения этих циклов я вычел время выполнения пустого цикла. Получились интересные результаты:

Как видно из результатов result = (i >= 0) ? i : -i; оказался быстрее всех, как и ожидалось. Но еще более интересна разница в скорости при скрытой конвертации типов у Math.Abs(), .

Надо будет потестить и другие вещи в том же духе.

  • zholobov

    Что же тут удивительного? Идём в Рефлектор и смотрим реализацию системной функции. Там есть человеческий контроль переполнения. За него и плата производительностью.

  • http://vitiy.info Victor Laskin

    Ясно дело, что результаты не являются чем-то удивительным. Просто они показывают сколько именно времени теряется на операции. Просто иногда приятно знать “Сколько вешать в граммах”.

  • zholobov

    В любом случае, экономить на Abs-ах имеет смысл разве что в вычметодах. А вот в очередной раз всесторонне исследовать вопрос соотношения скоростей Array, ArrayList и List было бы интересно. Это намёк. ;)

  • http://vitiy.info Victor Laskin

    Намек понял ;)