C# Waarom delen langzamer is dan vermenigvuldigen?

In programmeertalen en specifiek C# zijn er 4 rekenkundige bewerkingen die kunnen worden uitgevoerd: optellen, aftrekken, vermenigvuldigen en delen.

En vanuit een extern perspectief lijkt het misschien dat ze allemaal vergelijkbaar zijn qua prestaties, maar het blijkt dat een van hen veel langzamer is vergeleken met de andere drie.

Welke is langzamer, vraag je je misschien af? Divisie.

Volgens dit HP-papier:

Het berekenen van drijvende-kommadeling en vierkantswortel duurt aanzienlijk langer dan optellen en vermenigvuldigen. De laatste twee worden rechtstreeks berekend, terwijl de eerste meestal worden berekend met een iteratief algoritme. De meest gebruikelijke benadering is om een ​​delingsvrije Newton-Raphson-iteratie te gebruiken om een ​​benadering te krijgen van het omgekeerde van de noemer (deling) of de wederkerige vierkantswortel, en vervolgens te vermenigvuldigen met de teller (deling) of het invoerargument (vierkantswortel).

Om de bovenstaande verklaring te verifiëren, besloot ik een eenvoudige test uit te voeren met behulp van de onderstaande code:

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

Kortom, ik heb een miljoen optellingen, aftrekkingen, vermenigvuldigingen en delingen uitgevoerd voor de twee willekeurige getallen en de tijd gemeten die elk van hen nodig had om te verwerken. De test werd 5 keer herhaald, en hier is het resultaat:

  • Het toevoegen duurde gemiddeld 0,0004 seconden
  • Het aftrekken duurde gemiddeld 0,0003 seconden
  • Vermenigvuldiging duurde gemiddeld 0,0003 seconden
  • De divisie duurde gemiddeld 0,0044 seconden

Het resultaat toonde aan dat optellen, aftrekken en vermenigvuldigen qua prestaties vergelijkbaar zijn, maar dat delen ongeveer 1100% langzamer lijkt te gaan.

Geen klein verschil, wat tot de conclusie leidt dat het altijd beter is om waar mogelijk vermenigvuldigen in plaats van delen te gebruiken. Als u het getal bijvoorbeeld door 2 moet delen, kunt u het het beste met 0,5 vermenigvuldigen.

Voorgestelde artikelen
Waarom is Square Root een trage bewerking in C#?
Arne's C# Chronicles en best practices voor coderen
Ultieme laptopgids voor C#-ontwikkelaars
7 effectieve tips om C# sneller te leren
Een handleiding voor het schrijven en ophalen van gegevens uit multi-threaded code in C#
Tips voor het vinden van een droombaan voor aspirant-C#-ontwikkelaars
Beste verzekeringsopties voor C#-ontwikkelaars