Wenn der Code-Schreiber keine Ahnung von Compiler hat, sich aber auf ihn und seine Optimierungsalgorithmen verlässt …

Es gibt Code-Schreiberlinge, die glauben tatsächlich, dass „der Compiler eh alles optimiert„.
Andere glauben sogar, dass der Compiler eine gewisse Intelligenz besitzt.
Dann gibt es noch die Code-Schreiberlinge, die glauben, dass es gut ist, wenn sie jede Methode mit einem Try-Catch-Block zu versehen. Nachdem Motto „Bringt nichts, schadet nichts“ und/oder „Doppelt hält besser„.


Schauen wir uns das ganze Mal genauer an.
Wieder mal ein Stück Code aus freie Wildbahn (Industrie):

// Listing 1 (ugly code)

void Main()
{
	Console.WriteLine(GetSomething(0));
}

public double GetSomething(int value)
{
    try
    {
        return 0;
    }
    catch(Exception ex)
    {
        return 0;
    }
}

Man stelle sich nun vor (das wird mir niemand glauben) es gäbe ein SW-System mit hundert und mehr solche Methoden wie „GetSomething(int)„.

Der folgende Code tut exakt das Gleiche, nur viel CPU und Speicher freundlicher, überschaubarer, verständlicher und einfacher zu lesen:

// Listing 2 (better code)

public const double DBL_CONST = 0.0;

void Main()
{
	Console.WriteLine(0);
}

Und nun schauen wir uns mal an, was der Compiler:

  • Optimiert, und es dann
  • in „Intermediate Language“ (IL) Befehle für CLR übersetzt, und anschließen für den echten CPU (Hardware)
  • ins Assembler übersetzt

Fangen wir mal mit Listing 1 (ugly code) an:

Von links nach rechts: C# optimiert, IL, ASM (intel x64)

Man stelle sich vor der Code oben wird in einer Schleife immer wieder aufgerufen …

Und nun schauen wir uns Listing 2 (better code) an:

Von links nach rechts: C# optimiert, IL, ASM (intel x64)

Wie man sieht, wird der CPU bei Listing 1 (ugly code) unnötig beschäftigt. Man könnte meinen, es handle sich um eine „Beschäftigungstherapie“ für den CPU: „Das es eahm jo ned langweilig wird!„.

Wegen solche Code-Schreiberlinge, benötigen wir immer stärkere CPUs, noch mehr Cores pro Sockel, und immer mehr RAM. Von der Energieverschwendung und dem CO₂ Bilanz ganz zu schweigen.

Ugly vs Clean Code (zum Aufwärmen)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Ugly.Code
{
    public class GeoCalc
    {
        public double GetCS(double value)
        {

            double val1;
            double calc;


            val1 = value;
            calc = Math.Pow(val1, 2) * Math.PI;


            return calc;


        }

        public double GetSS(double value)
        {

            double val1;
            double calc;


            val1 = value;
            calc = Math.Pow(val1, 2);


            return calc;
        }

        // Some other methods...
    }
}

Warum ist der Code oben „Ugly“?

  1. Ungenutzte „using“ Zeilen
  2. Der Klassen-Name sagt nicht, was die Klasse enthält/anbietet/tut
  3. Die Methoden-Namen sagen nicht, was sie tun oder berechnen/zurückliefern
  4. Die Parameter-Namen sagen nicht, was sie enthalten
  5. Die lokalen Variable-Namen sagen nicht, was sie enthalten
  6. Lokale Variablen kaschieren die Parameter und dessen Werte, machen den Algorithmus schwer verständlich
  7. Unnötige Leerzeilen verlängern unnötig die Methode. Man muss mehr scrollen und mit den Augen rauf & runterschauen.

Die Klasse „GeoCalc“ von Oben, könnte man auch so schreiben:

using System;

namespace Clean.Code
{
    public class GeometryCalculator
    {
        public double CalculateCircleSurface(double radiusLength)
        {
            return radiusLength * radiusLength * Math.PI;
        }


        public double CalculateSquareSurface(double sideLength)
        {
            return sideLength * sideLength;
        }

        // Some other methods...
    }
}