Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1832to1836
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Schneller ohne Sprungmarke?

Schneller ohne Sprungmarke?
25.05.2021 15:00:24
Dieter
Moin zusammen,
für eine Optimierungsaufgabe habe ich eine Prozedur geschrieben, die im Prizip zu funktionieren scheint.
Hier der auf das Wesentliche reduzierte Ausschnitt aus der wesentlich umfangreicheren Prozedur:

Sub OptLoop()
'declarations
'different limits for different I, currently best settings
Dim VarLimits(30), BestSet(30) As Integer
'loop variables, variables for optimization
Dim I, J, NewMax, OldMax As Integer
'variables and constants
'read values for array VarLimits from worksheet
RestartLoop:
'initialize
For I = 1 To 30
BestSet(I) = 0
Next I
OldMax = 0
NewMax = 0
For I = 1 To 30
For J = 1 To VarLimits(I)
'send current I and J to worksheet
'calculate worksheet using I and J to get NewMax
If NewMax > OldMax Then
GoTo RestartLoop
End If
'keep temporary maximum for next loop
OldMax = NewMax
'keep index J for current I
BestSet(I) = J
Next J
Next I
'send BestSet to worksheet
End Sub
Insgesamt funktioniert das recht gut. Allerdings ist die Applikation zeitkritisch. Daher meine Fragen, ob es
eine schnellere Alternative zur Sprungmarke gibt.
Weiterhin werden Sprungmarken immer wieder für "schlechten Programmierstil" gehalten. Bisher habe
ich aber keine zufriedenstellende Begründung dafür gefunden. Meiner Meinung nach muss eine Prozedur
laufen und keine Schönheitspreise gewinnen.
Vorab schon mal vielen Dank für Eure Hilfe
Dieter Krüsemann

11
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Schneller ohne Sprungmarke?
25.05.2021 16:47:34
Frank
Hallo Dieter!
Grundsätzlich geht das statt einer Sprungmarke:

Do
' Code...
If irgendeineBedingung Then Exit Do ' Beendet Do
' Code, der nicht mehr ausgeführt werden soll wenn Bedingung zutrifft...
Loop While True
Nebenbei: Auch ganz nützlich, um in For-Schleifen den nächsten Durchgang zu starten, ist folgendes. (Das ersetzt das Continue-Statement, das es in anderen Sprachen gibt, aber nicht in VBA.)

For I = 1 To irgendwas: Do
' Code...
If irgendeineBedingung Then Exit Do ' Springt raus und startet nächsten Durchgang
' mehr Code...
Loop While False: Next

In Deinem Fall ist es wegen der I- und J-Schleifen etwas komplizierter. Es könnte ungefähr wie folgt aussehen, aber je nach den NewMax-Werten, die Du in der Schleife aus dem Worksheet holst, könnte das zu einer Endlosschleife werden. (Ist auch in Deinem Beispiel so.)

Sub OptLoop()
Dim VarLimits(30), BestSet(30) As Integer
Dim I, J, NewMax, OldMax As Integer
Do      ' Dieses Do ersetzt die Sprungmarke.
Do  ' Dieses Do dient dazu, aus den Schleifen zu springen.
For I = 1 To 30
BestSet(I) = 0
Next I
OldMax = 0
NewMax = 0
For I = 1 To 30
For J = 1 To VarLimits(I)
'send current I and J to worksheet
'calculate worksheet using I and J to get NewMax
If NewMax > OldMax Then Exit Do
OldMax = NewMax
BestSet(I) = J
Next J
Next I
Loop While False
Loop While NewMax > OldMax
End Sub
Ob das nun wirklich schneller ist als eine Sprungmarke, wage ich allerdings zu bezweifeln. Manchmal sind Sprungmarken halt die schnellste Lösung. Was Du noch optimieren könntest wäre:

Dim BestSet As Variant
'initialize
Redim BestSet(30) As Integer
So ganz check ich leider nicht, was OptLoop eigentlich macht, aber vielleicht hilft es Dir.
Viele Grüße
Frank
Anzeige
AW: Schneller ohne Sprungmarke?
25.05.2021 17:27:49
GerdL
Moin Dieter,
die Variablendeklarationen sind unpräzise. Du erzeugst 30 x VarLimits(1 to 30) den NewMax u. ggf.
genauso oft den Rücksprung, im Zweifel alle BestSet-Werte erst im allerletzten Durchlauf.
Wie NewMax ermittelt wird, zeigst du nicht. Dort liegt höchstwahrscheinlich die Zeit.
Bestimmt kannst du diese Werte vorher in einen Variant einlesen.
Gruß Gerd
AW: Schneller ohne Sprungmarke?
25.05.2021 17:34:26
ChrisL
Hi Dieter
Wie Frank, würde ich ebenfalls annehmen, dass die Sprungmarke im Vergleich zum Loop keinen zeitlichen Unterschied macht. Wenn dann wären die Loops/Schleifen als Zeitfresser ganz generell zu hinterfragen. Es fehlt aber der Zusammenhang, um die Herangehensweise zu verstehen und ggf. Alternativen vorzuschlagen.
Bei der Haltung zu Sprungmarken geht es weniger um Performance, sondern um Übersichtlichkeit. Siehe dazu:
https://de.wikipedia.org/wiki/Spaghetticode
(Da dein Code sehr überschaubar ist, würde ich im konkreten Beispiel nicht von Spaghetti-Code sprechen.)
Erlaubt ist was Spass macht. Dennoch solltest du bedenken, ob der Code bei einer allfälligen Änderung in ein paar Monaten/Jahren noch intuitiv verständlich ist. Manchmal ist man schneller, wenn man sich die Zeit für einen halbwegs "schönen" Code nimmt und im Gegenzug einfacher Anpassungen vornehmen kann. Oft genug habe ich mich wegen meinen eigenen schlampigen Codes geärgert, wenn ich widererwarten doch etwas ändern musste oder ich habe mir bereits beim Debuggen die Zähne ausgebissen.
Abschliessend eine Kleinigkeit.
Dim I, J, NewMax, OldMax As Integer
Damit deklarierst du nur OldMax als Integer, alles andere bleibt Variant. Besser wäre:
Dim I As Integer, J As Integer, NewMax As Integer, OldMax As Integer
cu
Chris
Anzeige
AW: Schneller ohne Sprungmarke?
25.05.2021 19:29:57
Dieter
Vielen Dank für Eure Hinweise,
mir kommt es darauf an, bei Erfüllung einer bestimmten Bedingung wieder vor die Schleifen zu springen, um mit den bis zu dreißig vorher ermittelten Teiloptima wieder vorn einzusteigen, um diese als neue Anfangsbedingungen zu verwenden. Ohne Sprungmarke scheint das nicht zu funktionieren, weil Loops nur bis zu ihrem Anfang springen können, aber nicht vor ihren Anfang. Deshalb die Sprungmarke, die einzige in meinem gesamten Projekt.
Die Alternativlösung, in der die 30 Loops ineinander (ohne Sprungmarke) verschachtelt sind, an statt sie seriell mit Rücksprung ablaufen zu lassen, führen zu gigantischen Laufzeiten. Jedenfalls für meine Applikation liefert diese etwas ungewöhnliche Methode das gewünschte Optimum in sensationell kurzer Zeit.
Das, was Ihr als Spaghetticode bezeichnet, kenne ich aus der Steinzeit der Automatisierung als "Balkone programmieren", wenn die vorgesehenen Speicherbausteine nicht mehr ausreichten und mit neuen erweitert werden musste. Hier blieb nur der Hin- und Rücksprung, der besagte schreckliche Balkon.
Danke für Eure Hilfe, vielleicht kann ich mich beim nächsten Mal mit einer weiteren Geschichte aus der Automatisierungs-Steinzeit revanchieren.
Anzeige
AW: Schneller ohne Sprungmarke?
26.05.2021 17:11:25
ChrisL
Hi Dieter
Danke für die Rückmeldung und für die Zusatzgeschichte (gefällt mir).
cu
Chris
AW: Schneller ohne Sprungmarke?
25.05.2021 20:51:23
Daniel
Naja mit Sprungmarken kann man überall hin springen.
Dh es gibt kein zwingen logisches Ziel für einen Sprung.
Wenn man viele Sprungmarken einsetzt, wird der Code schnell unübersichtlich und eine falsch gesetzte Sprungmarke kann eine schwer zu entdeckenden Fehlerursache sein.
Sprungmarken sind halt in den meisten Fällen vermeidbar.
Das schließt aber nicht aus dass es Aufgabenstellungen gibt, deren optimale Lösung Sprungmarken verwendet, nur sind diese halt sehr selten.
Sprungmarken frei könnte man deine Aufgabe auch so programmieren:

Do
For I = 1 To 30
For J = 1 To VarLimits(I)
If NewMax > OldMax Then Exit For
Next
If J  30
Ob jetzt schneller ist, wage ich mal wegen der zusätzlichen IFs zu bezweifeln.
Aber egal wie du den Neustart der Schleifen realisierst: du musst in den relevanten Daten verändern irgendwas gegenüber dem Ausgangszustand verändern, damit du nicht in einer Endlosschleife landest.
Gruß Daniel
Anzeige
AW: Schneller ohne Sprungmarke?
25.05.2021 21:58:12
Dieter
Moin Daniel,
es kann keine Endlosschleife geben, weil das Kriterium zum Rücksprung vor die Schleife heißt:
Rücksprung, wenn das neue Maximum größer (nicht größer gleich) als des bisherige Maximum ist.
Wenn das Kriterium nicht erfüllt ist, findet der Rücksprung nicht statt, und die Schleifenkonstruktion
wird bis zum Ende durchlaufen.
Auf die If-Klauseln kann ich nicht verzichten, weil Parameter unter bestimmten Bedingungen zur
Verfügung stehen oder auch nicht. Diese Zustände werden dynamisch in dem Worksheet erzeugt,
mit dem das Makro kommuniziert. Die If-Klauseln blenden dann die teilweise umfangreiche
Behandlung irrelevanter Parameter Zeit sparend aus.
Beste Grüße
Dieter
Anzeige
AW: Schneller ohne Sprungmarke?
26.05.2021 00:05:56
Yal
Hallo zusammen,
bei mir stellt sich die Frage, ob eine "zeitkritische" Anwendung in Excel-VBA richtig beheimatet ist. Wenn man die "Real Time Processing in C" Vorlesung überlebt hat, diskutiert man nicht, ob Do-While oder Sprung.
Es kommt nur darauf an, wie viel in der Schleife gemacht wird, und ob alles notwendig ist. Ich habe so einen Do-While von 2 Std in 2 Sek optimieren können.
Bei gleicher Handling sollte die Unterschied zwischen Do-While und Sprung in Mikro-Sekunden Bereich bewegen.
Wenn die Daten doch in Excel sein müssen, dann sollte man sich Python+Pandas Dataframe + numba JIT anschauen. Vorausgesetzt es lässt sich parallelisieren.
VG
Yal
Anzeige
AW: Schneller ohne Sprungmarke?
26.05.2021 09:39:26
Dieter
Moin Yal,
"zeitkritisch" ist immer eine Sache der Applikation. Bei Prozesssteuerungen kann schon der Unterschied zwischen 0,1 und 1 Sekunde entscheidend sein. Bei meiner Applikation beginnt die bisher noch nicht erreichte Schmerzgrenze aus eigener Erfahrung bei 1 Minute. So lange das mit Excel VBA und einer optimierten Kommunikation zwischen den Makros und den Arbeitsblättern leistbar ist, werde ich bei dieser Lösung bleiben, und ich kann mir das Erlernen einer weiteren Programmiersprache sparen.
Bei mit stehen die Ergebnisse der Applikation im Vordergrund und nicht der Weg dahin, wobei ich Wert auf einen soliden und gut kommentierten Programmcode "ohne Holzhämmer und Brecheisen" lege.
Trotzdem vielen Dank für Deine Hinweise.
Dieter
Anzeige
AW: Schneller ohne Sprungmarke?
26.05.2021 12:11:52
Frank
Hallo Dieter,
Noch was am Rande: Wenn ich das richtig verstanden habe, schreibst Du ermittelte Werte in ein Worksheet. Benutzt Du dort vielleich automatische Formatierungen? Die sind nämlich unglaubliche Zeitfresser! Ob das ein Bug ist oder gewollt, weiß ich nicht, aber wenn man per VBA nur einen einzigen Wert in eine automatisch formatierte Zelle einträgt, scheint Excel alle automatischen Formatierung in allen zurzeit geöffneten Workbooks neu zu berechnen – ganz egal ob diese miteinander verknüft sind oder nicht.
Viele Grüße
Frank
AW: Schneller ohne Sprungmarke?
26.05.2021 12:51:36
Yal
Hallo Dieter,
Mit der ergäzenden Erklärung kann ich tatsächlich die Sachlage besser zuordnen.
Es geht in deinem Fall nicht um zeitkritische Problem, sondern lediglich um Performance.
Diese ist definitiv nicht in der Unterschied zwischen While-Loop und Sprünge zu suchen.
Eine komplette Analyse ist aber nur mit der kompletten Anwendung machbar.
VG
Yal
Anzeige

Links zu Excel-Dialogen

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige