C# Почему деление медленнее, чем умножение?

В языках программирования, в частности C#, можно выполнять 4 арифметических операции: сложение, вычитание, умножение и деление.

И со стороны может показаться, что все они схожи по производительности, но оказывается, что один из них намного медленнее по сравнению с тремя другими.

Какой из них медленнее, спросите вы? Дивизия.

Согласно этой статье HP:

Деление с плавающей запятой и квадратный корень требуют значительно больше времени, чем сложение и умножение. Последние два вычисляются напрямую, а первые обычно вычисляются с помощью итерационного алгоритма. Наиболее распространенный подход - использовать итерацию Ньютона-Рафсона без деления, чтобы получить приближение к обратной величине знаменателя (деление) или обратному квадратному корню, а затем умножить на числитель (деление) или входной аргумент (квадратный корень)..

Чтобы проверить утверждение выше, я решил запустить простой тест, используя приведенный ниже код:

        //Generate two random numbers
        var rand = new System.Random();
        float a = rand.Next();
        float b = rand.Next();

        Debug.Log("Number a: " + a + " Number b: " + b);

        System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();

        watch.Start();
        //Addition
        for (int i = 1; i < 1000000; i++)
        {
            float tmp = a + b;
        }
        watch.Stop();
        //Output
        Debug.Log("Addition took: " + watch.Elapsed.TotalSeconds.ToString("0.0000") + " seconds");

        watch.Reset();
        watch.Start();
        //Subtraction
        for (int i = 1; i < 1000000; i++)
        {
            float tmp = a - b;
        }
        watch.Stop();
        //Output
        Debug.Log("Subtraction took: " + watch.Elapsed.TotalSeconds.ToString("0.0000") + " seconds");

        watch.Reset();
        watch.Start();
        //Multiplication
        for (int i = 1; i < 1000000; i++)
        {
            float tmp = a * b;
        }
        watch.Stop();
        //Output
        Debug.Log("Multiplication took: " + watch.Elapsed.TotalSeconds.ToString("0.0000") + " seconds");

        watch.Reset();
        watch.Start();
        //Division
        for (int i = 1; i < 1000000; i++)
        {
            float tmp = a / b;
        }
        watch.Stop();
        //Division
        Debug.Log("Division took: " + watch.Elapsed.TotalSeconds.ToString("0.0000") + " seconds");

По сути, я выполнил миллион операций сложения, вычитания, умножения и деления двух случайных чисел и измерил время, необходимое для обработки каждого из них, тест был повторен 5 раз, и вот результат:

  • Добавление в среднем занимало 0,0004 секунды.
  • Вычитание в среднем занимало 0,0003 секунды.
  • Умножение в среднем занимало 0,0003 секунды.
  • Деление в среднем занимало 0,0044 секунды.

Результат показал, что сложение, вычитание и умножение аналогичны по производительности, но деление происходит примерно на 1100% медленнее.

Разница немалая, что приводит к выводу, что всегда лучше использовать умножение вместо деления, когда это возможно. Например, если вам нужно разделить число на 2, лучше всего умножить его на 0,5.

Рекомендуемые статьи
Почему квадратный корень — медленная операция в C#?
Руководство по написанию и получению данных из многопоточного кода на C#
Полное руководство по ноутбукам для разработчиков C#
Введение в С#
7 эффективных советов, которые помогут быстрее изучить C#
Освоение основ программирования на C#
Советы по поиску работы мечты для начинающих разработчиков C#