So, habe jetzt ein bißchen rumgetestet.
Grundsätzlich iteriert man bei Collections über
|
Quellcode
|
1
|
for each obj in Collection
|
bei Arrays über den Index mit
|
Quellcode
|
1
|
for Index = LBound(array) to Ubound(array)
|
Dies ist auch aarays auch richtig schnell. Collection ist da lahmer, Vorteil ist die Bandbreite an Datentypen. Dictionary-Objecte sind hingegen wieder richtig schell.
Zur Geschwindigkeitsmessung habe ich einfach modulweit
|
Quellcode
|
1
2
|
Public Declare Function GetTickCount Lib "kernel32" () As Long
Public start As Long
|
gesetzt und kann damit in jeder Prozedur mittels
|
Quellcode
|
1
2
3
|
start = GetTickCount
'Code, welcher untersucht werden soll
Debug.Print "time: " & (GetTickCount - start) / 1000 & " s"
|
die benötige Zeit auslesen.
Meist macht es nur in Schleifen Sinn, dafür muss man etwas rumtesten, dass der Code ca. zwischen 1 und 10 Sekunden läuft. Dann kann man die Performance erhöhen. Natürlich ist diese Methode nicht sehr genau, ist die reine Rechenzeit nie für Performancemessung, aber man bekokommt ganz gute und auch stabile Ergebnisse. Wenn man Lust hat, kann man sich auch ne eigene Klasse für den Timmer mit den 2 Methoden start und stop bauen, aber bei insgesamt 4 zeilen Code halte ich das für unnötig, hinzu könnte der Overhead die Performancemessung verfälschen und ich müsste ihn erst wieder herausrechnen.
Man sollte beispielsweise
immer die Maximum-Function selbst definieren mittels
|
Quellcode
|
1
2
3
|
Public Function max(x, y)
If (x >= y) Then max = x Else max = y
End Function
|
anstatt
|
Quellcode
|
1
2
3
|
Public Function max(x, y)
max = WorksheetFunction.Max(x, y)
End Function
|
zu benutzen. Das ist ca. 50x schneller, also von Größenordnung ln(50)/ln(10) = 1.7. Krass!
Wenn man zudem noch die Funktionen nicht als Variant sondern als explizter Datentyp (Double, Integer, Long) definiert, ist die selbstgeschriebene Function noch einmal 58% schneller - bei der Worksheet.Function gibt es dagegen keinen merklichen Geschwindigkeitsvorteil.
Ansonsten benutze ich für das Proket recht intensiv selbstdefinierte Klassen. Leider braucht man für jede neue Klasse ein neues Klassenmodul.

Ist jetzt nicht unbedingt so der Performancebringer, aber für die Lesbarkeit des Codes extrem hilfreich, außerdem denkt es sich so leichter in Problemlösungskategorien.
So ein größeres Projekt ist mal ne nette Erfahrung für einen, der sonst immer nur rein Lösungsorientiert programmiert hatte und deswegen nur prozedural.
Mittels der Klassenlösung kann ich auch viele 1-dimensionale Arrays verwenden. Erstens bringt dies auch wieder Geschwindigkeit, da VBA Excel 1-dim arrays sehr effizient benutzen kann, zum anderen fällt dann das resize problem nicht mehr so ins Gewicht.
Theoretisch könnte ich noch mti CopyMemory oder ähnlichen Dingen direkt an der Speicheradresse arbeiten, aber denke das ist hier nicht notwendig - wäre aber sehr schnell.
So, dass waren mal ein paar Erfahrungen, welche ich in den letzten Tagen zum Thema gemacht habe. Hilft vielleicht dem ein oder anderem.