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.