C# Varför division är långsammare än multiplikation?

I programmeringsspråk och specifikt C# finns det 4 aritmetiska operationer som kan utföras: addition, subtraktion, multiplikation och division.

Och från ett externt perspektiv kan det tyckas att alla är lika när det gäller prestanda, men det visar sig att en av dem är mycket långsammare jämfört med de andra 3.

Vilken är långsammare kan du fråga dig? Division.

Enligt detta HP-papper:

Flyttalsdivision och kvadratrot tar betydligt längre tid att beräkna än addition och multiplikation. De två sistnämnda beräknas direkt medan de förra vanligtvis beräknas med en iterativ algoritm. Det vanligaste tillvägagångssättet är att använda en divisionsfri Newton-Raphson iteration för att få en approximation till det reciproka av nämnaren (division) eller den reciproka kvadratroten, och sedan multiplicera med täljaren (division) eller inmatningsargument (kvadratrot).

För att verifiera påståendet ovan bestämde jag mig för att köra ett enkelt test med koden nedan:

        //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");

I grund och botten körde jag en miljon additioner, subtraktioner, multiplikationer och divisioner för de två slumpmässiga talen och mätte tiden var och en av dem tog att bearbeta, testet upprepades 5 gånger, och här är resultatet:

  • Adderingen tog i genomsnitt 0,0004 sekunder
  • Subtraktion tog i genomsnitt 0,0003 sekunder
  • Multiplikation tog i genomsnitt 0,0003 sekunder
  • Division tog i genomsnitt 0,0044 sekunder

Resultatet visade att addition, subtraktion och multiplikation liknar varandra när det gäller prestanda, men division verkar vara cirka 1100 % långsammare.

Inte en liten skillnad, vilket leder till slutsatsen att det alltid är bättre att använda multiplikation istället för division när det är möjligt. Till exempel, när du behöver dividera talet med 2, är det bäst att multiplicera det med 0,5 istället.

Föreslagna artiklar
Varför är kvadratrot en långsam operation i C#?
Introduktion till C#
En guide till att skriva och hämta data från flertrådad kod i C#
Bemästra grunderna i C#-programmering
Tips för att få ett drömjobb för blivande C#-utvecklare
Viktiga programmeringstips för C#-utvecklare
Arnes C# Chronicles and Coding Best Practices