In diesem Tipp & Trick geht es um den Einsatz eines VBA Timers zur Messung der Ausführungsdauer von VBA Steuerungen. Um die Perfomance eines Modells zu überprüfen und zu verbessern, ist es von Vorteil, einen Timer zu nutzen, der die Ausführungsdauer von VBA Code misst. So lässt sich zum Beispiel bestimmen, welche Steuerungen besonders viel Rechenzeit benötigen.
Eine zusätzliche VBA-Klasse
Der Timer basiert auf einer in VBA selbst-definierten Klasse namens CTimer. Der Code für die Klasse stammt im Original von Stackoverflow (Klasse CTimer) und wurde für den Gebrauch in WWB-COM und WWB.NET angepasst. Die Klasse und ein Demomodel sind hier im Downloadbereich zu finden (siehe unten). Der Code der Klasse muss zur Nutzung in ein separates Makro eingefügt werden. In der Klasse CTimer kann die Methode CTimer.startCounter aufgerufen werden, um den Timer zu starten. Mit der Eigenschaft CTimer.TimeElapsed wird die vom Start des Timers vergangene Zeit in Millisekunden ausgelesen.
Die Ausführungsdauer messen
In einfachen Beispielen wollen wir zeigen, welchen Einfluss unterschiedliche Syntax auf die Ausführungsdauer einer VBA-Steuerung hat. Um die gemessene Zeit in einer Tabelle zu speichern, wird in diesen Beispielen die Subroutine Store_Measured_Time aufgerufen. In dieser Subroutine wird die Zeit für die Ausführung eines gemessenen VBA Codes für alle seine Aufrufe aufsummiert. Zusätzlich wird die maximale Ausführungszeit, die Anzahl an Aufrufen und die durchschnittliche Ausführungsdauer für die Steuerung gespeichert und in eine Tabelle geschrieben. Falls es für den gemessenen Code noch keine Zeile in der Tabelle gibt, wird eine neue eingefügt. Diese Subroutine hat den Namen der gemessenen Steuerung und die Timer Variable der Klasse Timer als Argument:
Sub Store_Measured_Time(measured_sub_name As String, ByRef sub_timer As CTimer) 'time_elapsed As Double)
Dim time_elapsed As Double
time_elapsed = sub_timer.TimeElapsed 'read out the passed time
Dim row As Long
row = t_Timer.FindRow(measured_sub_name) 'look in the table if there is already a line for the sub
If row < 0 Then 'if there is no line for the sub yet
row = t_Timer.RowCount + 1
t_Timer(row,0) = measured_sub_name
t_Timer(row,"Total Time [ms]") = 0
t_Timer(row,"Number") = 0
t_Timer(row,"Mean [ms]") = 0
t_Timer(row,"Max [ms]") = 0
End If
t_Timer(measured_sub_name,"Total Time [ms]") += time_elapsed 'add the elapsed time
t_Timer(measured_sub_name,"Number") += 1 'count the calls of the sub
t_Timer(measured_sub_name,"Mean [ms]") = t_Timer(measured_sub_name,"Total Time [ms]")/t_Timer(measured_sub_name,"Number") 'calculate the mean duration of the sub
If time_elapsed > t_Timer(measured_sub_name,"Max [ms]") Then
t_Timer(measured_sub_name,"Max [ms]") = time_elapsed 'saves the maximum time
End If
End Sub
Dieses Sub stellt ist nur ein Bespiel dafür, wie man die Ergebnisse des Timers auswerten kann. Natürlich kann der Code den persönlichen Wünschen entsprechend angepasst und eigene KPIs berechnet werden.
Wenn Store_Measured_Time so genutzt werden soll, muss die Tabelle t_Timer z. B. in der Simulationsinitialisierung zunächst initiiert werden.
Dim t_Timer As Table
Private Sub Simulation_Init() Handles Simulation.Init
t_Timer = New Table
t_Timer = Read_Table("Timer Template",1,1,0,0,True,True)
End Sub
Im Downloadbereich befindet sich ein Beispielprojekt, bei dem das Parameterworkbook das Tabellenblatt Timer Template enthält, welches eine leere Tabelle mit den gewünschten Überschriften (Procedures, Total Time [ms], etc.) ist.
Beispiele
Zwei Schreibweisen von If-Statements vergleichen
Im ersten Beispiel wird die Syntax von If-Abfragen in einer Start-Steuerung überprüft.
'Version 1:
Sub OP_Start1(cop As OrderOperation)
Dim sub_timer As New CTimer
sub_timer.StartCounter 'starts the counter
If cop.Unit.Allocated = True Then
'do nothing
End If
Store_Measured_Time("OP_Start1",sub_timer)
End Sub
'Version 2:
Sub OP_Start2(cop As OrderOperation)
Dim sub_timer As New CTimer
sub_timer.StartCounter 'starts the counter
If cop.Unit.Allocated Then
'do nothing
End If
Store_Measured_Time("OP_Start2",sub_timer)
End Sub
In der Ergebnistabelle ist zu sehen, dass die erste Version der Steuerung etwas langsamer ist als die zweite. Die maximale Ausführungsdauer, die mittlere Dauer und die gesamte Dauer sind ebenfalls für die gleiche Anzahl an Aufrufen größer.
Procedures | Total Time [ms] | Number | Mean [ms] | Max [ms] |
OP_Start1 | 1,1016 | 100 | 0,011016 | 0,0569 |
OP_Start2 | 0,5958 | 100 | 0,005958 | 0,0102 |
Bitte beachten: Alle Werte sind spezifisch für den verwendeten Computer und des aktuellen Status des Computers.
Vergleich von zwei Schreibweisen für Rechenoperationen
In dem zweiten Beispiel werden zwei Versionen für die Syntax für das Verdoppeln der Operationsdauer in einer Parametersteuerung verglichen.
'Version 1:
Sub OP_Parameter1(cop As OrderOperation, mop As RecipeOperation)
Dim sub_timer As New CTimer
sub_timer.StartCounter
cop.Duration = cop.Duration * 2
Store_Measured_Time("OP_Parameter1",sub_timer)
End Sub
'Version 2:
Sub OP_Parameter2(cop As OrderOperation, mop As RecipeOperation)
Dim sub_timer As New CTimer
sub_timer.StartCounter
cop.Duration *= 2
Store_Measured_Time("OP_Parameter2",sub_timer)
End Sub
In den Ergebnissen ist zu sehen, dass die zweite Version fast doppelt so schnell ist, wie die erste. Der Maximalwert für die Ausführung der Steuerung ist für beide Versionen vergleichbar, aber die Gesamtausführungszeit und die Durchschnittszeit unterscheiden sich sehr.
Procedures | Total Time [ms] | Number | Mean [ms] | Max [ms] |
OP_Parameter1 | 1,1806 | 100 | 0,011806 | 0,0282 |
OP_Parameter2 | 0,6375 | 100 | 0,006375 | 0,0278 |
Bitte beachten: Alle Werte sind spezifisch für den verwendeten Computer und des aktuellen Status des Computers.
Teilanlagenbelegungssteuerung V12 vs. V13
In einem weiteren Beispiel wird das Verhalten von Teilanlagenbelegungssteuerung verglichen. Der Tipp & Trick Neue Steuerungen für Unit Pools in INOSIM 13 anwenden beschreibt das unterschiedliche Verhalten der Steuerung detailliert. In der ersten Version wird das alte Standardverhalten von INOSIM 12 genutzt. Dabei wird die Steuerung wiederholt aufgerufen und eine Teilanlage vorgeschlagen, diese kann zugelassen oder abgelehnt werden. Falls die vorgeschlagene Teilanlage abgelehnt wird, wird die Steuerung für eine andere Teilanlage wieder aufgerufen. Ab INOSIM 13 ist es möglich im ersten Aufruf der Steuerung zu bestimmen, welche Teilanlagen erlaubt sind. Dann wird nur ein Aufruf benötigt. Welchen Geschwindigkeitsvorteil bietet diese Möglichkeit?
Procedures | Total time [ms] | Number | Mean [ms] | Max [ms] |
Product_Tank_V12 | 17124,2879 | 399329 | 0,04288266 | 219,431 |
Product_Tank_V13 | 660,2568 | 3901 | 0,16925322 | 0,9836 |
Bitte beachten: Alle Werte sind spezifisch für den verwendeten Computer und des aktuellen Status des Computers.
Die durchschnittliche Ausführungszeit für die V12-Variante beträgt nur ungefähr ein Viertel der V13-Steuerung. Die Steuerung wird allerdings ca. 100-mal häufiger aufgerufen als die V13-Version, da sie mehrfach aufgerufen wird, bis eine passende Teilanlage gefunden wurde. Insgesamt ergibt sich daher in diesem konkreten Anwendungsfall ein 25-facher Geschwindigkeitsvorteil für die V13-Steuerung.
Randnotiz
Beachten Sie, dass das Messen der Ausführungszeit selbst auch zusätzliche Rechenzeit benötigt. Falls der VBA Code zum Starten des Timers und zum Speichern der Werte nicht mehr benötigt wird, sollten die entsprechenden Zeilen auskommentiert oder gelöscht werden. Alternativ kann man einen globalen Schalter nutzen, der den VBA-Timer an- und ausschaltet.
(nur für registrierte INOSIM Kunden)
- Beispielmodell VBA Timer.xml
- CTimer Klassencode
- PDF-Ausdruck dieses Tipps & Tricks
Fragen?
Möchten Sie mehr über dieses Thema erfahren oder haben weitere Fragen? Bitte kontaktieren Sie uns.
Mehr Tipps & Tricks
Arbeiten mit externen Excel-Arbeitsmappen
Arbeiten mit externen Excel-Arbeitsmappen Neben dem Zugriff auf die in INOSIM eingebaute Excel-Arbeitsmappe (siehe Tipp Nutzen Sie Ihr Excel-VBA-Wissen bei der Arbeit mit INOSIM), kann mit Hilfe…
Die Abfolge von INOSIM Ereignisaufrufen
Erfahrenen Anwendenden von INOSIM ist bewusst, dass sie mit einer ereignisdiskreten Simulationssoftware arbeiten. Für die meisten dieser Ereignisse können VBA-Steuerungen aufgerufen werden, um das Simulationsverhalten…
Transfer-Graph Visualisierung mit Tableau
Dieser Tipp & Trick stellt Ihnen ein praktisches Werkzeug zur Visualisierung und Analyse von Transfers in Ihrem Modell mit der BICON-Erweiterung zur Verfügung. Die Tableau-Arbeitsmappe…