Was ist schneller C# oder VBA?

In jedem Fachgebiet gibt es Fragestellungen, die von den in die Materie involvierten Personen sofort richtig beantwortet werden. Das Gebiet der Softwareentwicklung bildet da natürlich keine Ausnahme. Ich glaube, jedem Entwickler dürfte klar sein, dass zwischen VBA und C# (beide aus dem Hause Microsoft stammend) Welten liegen. Deswegen geht es in diesem Beitrag nicht um die Frage „Ist C# schneller als VBA?“, sondern vielmehr „Um welchen Faktor ist C# schneller als VBA?“

Vergleichsdurchführung

Um einen Vergleich anzustellen, habe ich in beiden Sprachen ein einfaches Programm mit identischem Aufbau entwickelt, welches eine bestimmte Anzahl von Primzahlen ermittelt. Bei der Programmentwicklung ging es dabei nicht darum, ein möglichst effizientes Algorithmus (denn das ist es definitiv nicht) für die Primzahlenermittlung zu entwickeln, sondern darum, den Rechner einfach eine Weile beschäftigen zu können. Die Generierung von 20.000 Primzahlen sollte dafür mehr als ausreichend sein.

Ergebnis

Bei dem Laufzeitvergleich der beiden Programme ging es nicht wirklich um Millisekunden, sodass ich ganz unkonventionell einfach mit meinem Handy die Zeit stoppte. Ich hoffe nur, dass der Test durch die währenddessen auf dem Rechner abgespielte Musik nicht verfälscht wurde 🙂

Fazit

Laufzeit C#-Programm: 5 Sekunden

Laufzeit VBA-Programm: 24 Sekunden

Wie es auch zu erwarten war, ist das Ergebnis mehr als eindeutig. Um ehrlich zu sein, hat mich aber fast der 5 fache Performanceabstand dennoch überrascht. Aber letztendlich gleicht die Softwareentwicklung in vielerlei Hinsicht dem Handwerk, wo für jeden Einsatzzweck unterschiedliche Werkzeuge gibt. Rein theoretisch kann man auch mit einer Bohrmaschine Nägel in die Wand reinhämmern. Zum Bohren kann diese aber dennoch viel sinnvoller eingesetzt werden :-).

So ist es auch mit VBA, womit sich echt gut kaufmännische Prozesse automatisieren und Anwendungen für mittlere Datenmengen realisieren lassen. Für hoch performante Anwendungen, die Millionen von Einzeloperationen ausführen, wie zum Beispiel der oben durchgeführte Vergleich mit den Primzahlen, gibt es geeignetere Programmiersprachen.

Anschließend habe ich noch aus Interesse noch einen weiteren Performancevergleich durchgeführt, nämlich mit PowerShell. Mit dieser Scriptsprache hatte ich bisher kaum Berührungspunkte. Das damit entwickelte Programm am langsamsten und hat mit rund 250 Sekunden rund 50zig fache des C#- und rund 10fache des-VBA-Programms benötigt. Auch bei dieser Sprache gilt, dass sie nicht unbedingt für hoch performante Operationen geeignet ist.

VBA-Quellcode

Private Sub startTest()
    Dim lngPrimeNumbers()   As Long
    Dim varPrimeNumber      As Variant
    
    lngPrimeNumbers = getPrimeNumbers(20000)
   
    Debug.Print "done"
End Sub

Private Function getPrimeNumbers(numberOfPrimeNumbers) As Long()

    Dim lngPrimeNumbers()   As Long
    Dim lngPrimeNumberIndex As Long
    Dim lngPrimeCandidate   As Long
    
    ReDim lngPrimeNumbers(1 To numberOfPrimeNumbers) As Long
    
    lngPrimeNumberIndex = 1
    lngPrimeCandidate = 2
    
    Do While (numberOfPrimeNumbers >= lngPrimeNumberIndex)
        If isPrimeNumber(lngPrimeCandidate) Then
            lngPrimeNumbers(lngPrimeNumberIndex) = lngPrimeCandidate
            lngPrimeNumberIndex = lngPrimeNumberIndex + 1
        End If
        
        lngPrimeCandidate = lngPrimeCandidate + 1
    Loop
    
    getPrimeNumbers = lngPrimeNumbers

End Function
    
    
Private Function isPrimeNumber(primeNumber As Long) As Boolean
    
    Dim lngIndex        As Long
    Dim bolPrimeNumber  As Boolean
    
    bolPrimeNumber = True
    
    For lngIndex = 2 To primeNumber - 1
    
        If primeNumber Mod lngIndex = 0 Then
            bolPrimeNumber = False
            Exit For
        End If
    
    Next lngIndex
    
    isPrimeNumber = bolPrimeNumber
    
End Function

C#-Quellcode

using System;

namespace Primzahlen
{

    internal class Program
    {
        static void Main(string[] args)
        {
            int[] primes = PrimzahlGenerator.GetPrimNumbers(20000);

            StringBuilder t = new StringBuilder();

            Console.WriteLine("Done");
            Console.ReadKey();
        }
    }
	
	
    internal static class PrimzahlGenerator
    {
        internal static int[] GetPrimNumbers(int numberOfPrimeNumbers)
        {
            int[] primeNumbers = new int[numberOfPrimeNumbers];
            int primeNumberIndex = 0;

            int i = 2;
            while(numberOfPrimeNumbers > primeNumberIndex)
            {
                if (IsPrimeNumber(i))
                {
                    primeNumbers[primeNumberIndex] = i;
                    primeNumberIndex++;
                }

                i++;
            }

            return primeNumbers;
        }

        private static bool IsPrimeNumber(int primeNumber)
        {
            for (int i = 2; i < primeNumber; i++)
            {
                if (primeNumber % i == 0)
                {
                    return false;
                }
            }

            return true;
        }
    }
}

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert