| Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
| Autor |
Nachricht |
bplumhoff@gmail.com
Anmeldedatum: 01.01.1970 Beiträge: 45
|
Verfasst am: Di Sep 19, 2006 2:07 am Titel: Case vs if |
|
|
Hallo Norbert,
ein kurzer Test mit FastExcel unter Excel 2002 liefert mir bei 10,000
Auswertungen der folgenden Funktionen:
Public Function Vergleich1(r As Range) As String
Select Case r
Case 0 To 10
Vergleich1 = "erste Dekade"
Case 11 To 20
Vergleich1 = "zweite Dekade"
Case 21 To 30
Vergleich1 = "dritte Dekade"
End Select
End Function
Public Function Vergleich2(r As Range) As String
If r >= 0 And r <= 10 Then
Vergleich2 = "erste Dekade"
ElseIf r >= 11 And r <= 20 Then
Vergleich2 = "zweite Dekade"
ElseIf r >= 21 And r <= 30 Then
Vergleich2 = "dritte Dekade"
End If
End Function
Public Function Vergleich3(r As Range) As String
Vergleich3 = "erste Dekade"
End Function
folgendes Ergebnis:
Vergleich1 (Case) 193.60 Millisekunden
Vergleich2 (If) 129.26 Millisekunden
Vergleich3 (leeres Makro) 84.46 Millisekunden
Die If Abfragen brauchen also etwa 129.26 - 84.46 = 50 ms
Die Case Anweisung benoetigt ca 193.60 - 84.46 = 110 ms
Das heisst die Ifs sind (in diesem Beispiel!!) mehr als doppelt so
schnell.
Ich denke, es kommt immer auf den Anwendungsfall an. Wenn es also
kritisch wird, braucht man ein profiling tool.
HTH,
Bernd
.
|
|
| Nach oben |
|
 |
bplumhoff@gmail.com
Anmeldedatum: 01.01.1970 Beiträge: 45
|
Verfasst am: Di Sep 19, 2006 2:19 am Titel: Case vs if |
|
|
Sorry, da war ein fataler Wurm drin:
Die Zeiten von If und Case waren vertauscht.
Richtig ist, was Melanie auch meinte: Die Case Anweisung ist schneller,
nach meiner Messung etwas mehr als doppelt so schnell.
Viele Gruesse,
Bernd
bplumhoff [at] gmail.com wrote:
> Hallo Norbert,
>
> ein kurzer Test mit FastExcel unter Excel 2002 liefert mir bei 10,000
> Auswertungen der folgenden Funktionen:
>
> Public Function Vergleich1(r As Range) As String
> Select Case r
> Case 0 To 10
> Vergleich1 = "erste Dekade"
> Case 11 To 20
> Vergleich1 = "zweite Dekade"
> Case 21 To 30
> Vergleich1 = "dritte Dekade"
> End Select
> End Function
>
> Public Function Vergleich2(r As Range) As String
> If r >= 0 And r <= 10 Then
> Vergleich2 = "erste Dekade"
> ElseIf r >= 11 And r <= 20 Then
> Vergleich2 = "zweite Dekade"
> ElseIf r >= 21 And r <= 30 Then
> Vergleich2 = "dritte Dekade"
> End If
> End Function
>
> Public Function Vergleich3(r As Range) As String
> Vergleich3 = "erste Dekade"
> End Function
>
> folgendes Ergebnis:
> Vergleich1 (Case) 193.60 Millisekunden
> Vergleich2 (If) 129.26 Millisekunden
> Vergleich3 (leeres Makro) 84.46 Millisekunden
>
> Die If Abfragen brauchen also etwa 129.26 - 84.46 = 50 ms
>
> Die Case Anweisung benoetigt ca 193.60 - 84.46 = 110 ms
>
> Das heisst die Ifs sind (in diesem Beispiel!!) mehr als doppelt so
> schnell.
>
> Ich denke, es kommt immer auf den Anwendungsfall an. Wenn es also
> kritisch wird, braucht man ein profiling tool.
>
> HTH,
> Bernd
.
|
|
| Nach oben |
|
 |
bplumhoff@gmail.com
Anmeldedatum: 01.01.1970 Beiträge: 45
|
Verfasst am: Di Sep 19, 2006 3:38 am Titel: Case vs if |
|
|
Hi Michael,
richtig. Dann ist If doppelt so schnell wie Case.
Have fun,
Bernd
.
|
|
| Nach oben |
|
 |
bplumhoff@gmail.com
Anmeldedatum: 01.01.1970 Beiträge: 45
|
Verfasst am: Di Sep 19, 2006 7:11 am Titel: Case vs if |
|
|
Hi Michael,
ja. Das war Deine If Optimierung. Die Gotos waren langsamer als beide
anderen Alternativen.
Deinen Merksatz kann ich (leider) nachvollziehen und zur Nachahmung
empfehlen.
Moderne Compiler oder Pseudocode-Interpreter sollten den (intermediate)
Code eigentlich optimieren, dass alle genannten Varianten bei sauberer
Definition der Variablentypen in denselben (optimalen) Endcode
uebersetzt werden.
Aber ohne grosse Aufregung kann man denke ich immer empfehlen:
Ausprobieren, Laufzeit messen, selbst optimieren.
Viele Gruesse,
Bernd
PS: Ich bekomme fuer die FastExcel Empfehlung wirklich keine Provision
:-)
.
|
|
| Nach oben |
|
 |
Anmeldedatum: 01.01.1970 Beiträge: 312655
|
Verfasst am: Di Sep 19, 2006 9:52 am Titel: Case vs if |
|
|
Grüezi Norbert
Norbert Harz schrieb am 19.09.2006
> weil wir das in ähnlicher Art und Weise hier vor kurzem hatten.
>
> Was ist 'besseres' Design:
>
> Eine Case - Verschachtelung oder eine If / Ifelse?
> (BSP: 0 bis 10, 11 bis 20, 21 bis 30)
'Besseres Design' ist hierbei wohl Gusto.
Bei grösseren Vergleichen ist IMO ein Case-Vergleich 'schöner', da die
Struktur besser überschaubar bleibt.
Was die Verarbeitung angeht kann Case bei mehreren Vergleichen schneller
sein, da nur jeweils der Zutreffende abgearbeitet wird und alle andern dann
nicht mehr geprüft werden.
Bei entsprechend geschachtelten If-Then kann dies zwar auch erreicht
werden; darunter leidet dann aber wohl die Lesbarkeit des Codes.
Aber auch hier kommt es wohl auf den Einzelfall an.
Mit freundlichen Grüssen
Thomas Ramel ( [at] work)
--
- MVP für Microsoft-Excel -
[Win XP Pro SP-2 / xl2003 SP-1]
Microsoft Excel - Die ExpertenTipps tinyurl.com/cmned
.
|
|
| Nach oben |
|
 |
Anmeldedatum: 01.01.1970 Beiträge: 312655
|
Verfasst am: Di Sep 19, 2006 10:29 am Titel: Case vs if |
|
|
Grüezi Norbert, ich mal hier gleich noch die Ingrid
Thomas Ramel schrieb am 19.09.2006
>> Was ist 'besseres' Design:
>>
>> Eine Case - Verschachtelung oder eine If / Ifelse?
>> (BSP: 0 bis 10, 11 bis 20, 21 bis 30)
>
> 'Besseres Design' ist hierbei wohl Gusto.
>
> Bei grösseren Vergleichen ist IMO ein Case-Vergleich 'schöner', da die
> Struktur besser überschaubar bleibt.
>
> Was die Verarbeitung angeht kann Case bei mehreren Vergleichen schneller
> sein, da nur jeweils der Zutreffende abgearbeitet wird und alle andern dann
> nicht mehr geprüft werden.
>
> Bei entsprechend geschachtelten If-Then kann dies zwar auch erreicht
> werden; darunter leidet dann aber wohl die Lesbarkeit des Codes.
Hier ein Beispiel, das deinen Bedingungen entspricht; mir persönlich
gefällt der Select-Case-Block besser:
Public Sub Vergleich()
Select Case ActiveCell.Value
Case 0 To 10
MsgBox "erste Dekade"
Case 11 To 20
MsgBox "zweite Dekade"
Case 21 To 30
MsgBox "dritte Dekade"
End Select
If ActiveCell.Value >= 0 And ActiveCell.Value <= 10 Then
MsgBox "erste Dekade"
ElseIf ActiveCell.Value >= 11 And ActiveCell.Value <= 20 Then
MsgBox "zweite Dekade"
ElseIf ActiveCell.Value >= 21 And ActiveCell.Value <= 30 Then
MsgBox "dritte Dekade"
End If
End Sub
Mit freundlichen Grüssen
Thomas Ramel ( [at] work)
--
- MVP für Microsoft-Excel -
[Win XP Pro SP-2 / xl2003 SP-1]
Microsoft Excel - Die ExpertenTipps tinyurl.com/cmned
.
|
|
| Nach oben |
|
 |
Anmeldedatum: 01.01.1970 Beiträge: 312655
|
Verfasst am: Di Sep 19, 2006 10:38 am Titel: Case vs if |
|
|
Hallo Thomas, hallo Claus,
euch beiden erst einmal Danke.
Ok, ich hab mich vielleicht etwas missverständlich ausgedrückt.
Ich meinte mit Design nicht das Design des Quellcodes. Dass ich mir den
so schreibe, dass ich noch nachvollziehen kann, was ich da mache ist
eigentlich selbstverständlich.
Mir ging es mehr um die Entscheidung, welches ist Ressourcenschonender.
mfg,
Norbert
--
Bitte nur in die Newsgroup antworten.
Bei PM bitte nospam durch info ersetzen.
.
|
|
| Nach oben |
|
 |
Melanie Breden
Anmeldedatum: 01.01.1970 Beiträge: 3622
|
Verfasst am: Di Sep 19, 2006 10:46 am Titel: Case vs if |
|
|
Hallo Norbert,
Norbert Harz schrieb:
> Was ist 'besseres' Design:
>
> Eine Case - Verschachtelung oder eine If / Ifelse?
> (BSP: 0 bis 10, 11 bis 20, 21 bis 30)
ich tendiere auch zur Select Case-Anweisung, weil sie wesentlich übersichtlicher ist
und zudem der zu überprüfende Wert nur ein mal angegeben werden muss.
Die einzelnen Case-Abschnitte können ausserdem viel einfacher ausgedrückt werden.
Die Geschwindigkeit dürfte in diesem Beispiel minimal zugunsten von Select Case ausfallen,
weil in den If- und ElseIf Abfragen jedesmal zuerst Vergleiche berechnet werden müssen..
Hier ein Beispiel im Vergleich:
Public Sub CaseVsIf()
Dim lngZahl As Long
lngZahl = 15
Select Case lngZahl
Case 0 To 10
MsgBox lngZahl
Case 11 To 20
MsgBox lngZahl
Case 21 To 30
MsgBox lngZahl
Case Else
MsgBox "Zahl wird nicht überprüft"
End Select
If lngZahl > 0 And lngZahl <= 10 Then
MsgBox lngZahl
ElseIf lngZahl >= 11 And lngZahl <= 20 Then
MsgBox lngZahl
ElseIf lngZahl >= 21 And lngZahl <= 30 Then
MsgBox lngZahl
Else
MsgBox "Zahl wird nicht überprüft"
End If
End Sub
Mit freundlichen Grüssen
Melanie Breden
--
- Microsoft MVP für Excel -
Microsoft Excel - Die ExpertenTipps http://tinyurl.com/cmned
Das Excel-VBA Codebook http://excel.codebooks.de
Excel-Auftragsprogrammierung
.
|
|
| Nach oben |
|
 |
Anmeldedatum: 01.01.1970 Beiträge: 312655
|
Verfasst am: Di Sep 19, 2006 11:19 am Titel: Case vs if |
|
|
Grüezi Bernd
bplumhoff [at] gmail.com schrieb am 19.09.2006
> Richtig ist, was Melanie auch meinte: Die Case Anweisung ist schneller,
> nach meiner Messung etwas mehr als doppelt so schnell.
Danke für die Tests; das bestätigt die Annahmen.
Mit freundlichen Grüssen
Thomas Ramel ( [at] work)
--
- MVP für Microsoft-Excel -
[Win XP Pro SP-2 / xl2003 SP-1]
Microsoft Excel - Die ExpertenTipps tinyurl.com/cmned
.
|
|
| Nach oben |
|
 |
Anmeldedatum: 01.01.1970 Beiträge: 312655
|
Verfasst am: Di Sep 19, 2006 11:25 am Titel: Case vs if |
|
|
Hallo alle,
ok, ich danke euch für eure Überlegungen!
Ja wie gesagt: danke
Norbert
--
Bitte nur in die Newsgroup antworten.
Bei PM bitte nospam durch info ersetzen.
.
|
|
| Nach oben |
|
 |
Melanie Breden
Anmeldedatum: 01.01.1970 Beiträge: 3622
|
Verfasst am: Di Sep 19, 2006 11:48 am Titel: Case vs if |
|
|
Hallo Bernd,
bplumhoff [at] gmail.com schrieb:
> Sorry, da war ein fataler Wurm drin:
> Die Zeiten von If und Case waren vertauscht.
> Richtig ist, was Melanie auch meinte: Die Case Anweisung ist schneller,
> nach meiner Messung etwas mehr als doppelt so schnell.
danke für die genauen Berechnungen und den schnellen Nachschlag,
so ist die Excel-Welt doch wieder gerade gerückt :-)
Mit freundlichen Grüssen
Melanie Breden
--
- Microsoft MVP für Excel -
Microsoft Excel - Die ExpertenTipps http://tinyurl.com/cmned
Das Excel-VBA Codebook http://excel.codebooks.de
Excel-Auftragsprogrammierung
.
|
|
| Nach oben |
|
 |
Michael Zimmermann
Anmeldedatum: 01.01.1970 Beiträge: 2944
|
Verfasst am: Di Sep 19, 2006 12:21 pm Titel: Case vs if |
|
|
Hallo!
Thomas Ramel:
> > > Was ist 'besseres' Design:
> > >
> > > Eine Case - Verschachtelung oder eine If / Ifelse?
> > > (BSP: 0 bis 10, 11 bis 20, 21 bis 30)
> >
> > 'Besseres Design' ist hierbei wohl Gusto.
> >
> > Bei grösseren Vergleichen ist IMO ein Case-Vergleich
> > 'schöner', da die Struktur besser überschaubar bleibt.
> >
> > Was die Verarbeitung angeht kann Case bei mehreren
> > Vergleichen schneller sein, da nur jeweils der
> > Zutreffende abgearbeitet wird und alle andern dann
> > nicht mehr geprüft werden.
> >
> > Bei entsprechend geschachtelten If-Then kann dies zwar
> > auch erreicht werden; darunter leidet dann aber wohl
> > die Lesbarkeit des Codes.
>
> Hier ein Beispiel, das deinen Bedingungen entspricht; mir
> persönlich gefällt der Select-Case-Block besser:
>
> Public Sub Vergleich()
> Select Case ActiveCell.Value
> Case 0 To 10
> MsgBox "erste Dekade"
> Case 11 To 20
> MsgBox "zweite Dekade"
> Case 21 To 30
> MsgBox "dritte Dekade"
> End Select
>
> If ActiveCell.Value >= 0 And ActiveCell.Value <= 10
> Then MsgBox "erste Dekade"
> ElseIf ActiveCell.Value >= 11 And ActiveCell.Value <=
> 20 Then MsgBox "zweite Dekade"
> ElseIf ActiveCell.Value >= 21 And ActiveCell.Value <=
> 30 Then MsgBox "dritte Dekade"
> End If
> End Sub
Da hast Du der If-Variante aber bezüglich Performance
ein erhebliches Handicap aufgebürdet. Das ist unfair. ;-)
Bei Deinem Beispiel muß ActiveCell.Value sechsmal
ausgelesen werden. Mit einer Variablen geht das auch
mit einem Mal:
Dim z as Long
z = ActiveCell.Value
'Da Du in der Select-Case-Variante weder eine Prüfung auf
'den Wertebeeich noch einen Case Else vorgesehen hast,
'unterstelle ich mal, daß die Werte den Bereich 0 - 30
'sicher nicht verlassen.
If z < 11 _
Then
Msgox "Erstens"
Else
If z < 21 _
Then
Msgbox "Zweitens"
Else
Msgbox "Dritens"
End If
End If
Schon reduziert sich die Anzahl der Lesevorgänge vo 6 auf 1
und die Anzahl der Vergleiche von 6 auf 2.
Ein solches If-Konstrukt ist dann i. d. R. schneller als
Select-Case.
Eine ebenfalls sehr flotte Variante ist das böse GoTo
If z<11 Then Msgox "Erstens": Goto Weiter
If z<21 Then Msgox "Zweitens": Goto Weiter
Msgox "Drittens"
Weiter:
Aber - und da ist Dir volkommen zuzustimmen - am besten
lesbar ist sicher das Select-Case.
Bei allen Varianten kann übrigens das durchschnittliche
Laufzeitverhalten verbessert werden, wenn man den
wahrscheinlichsten Fall zuerst prüft.
Gruß aus Mainz
Michael
.
|
|
| Nach oben |
|
 |
Anmeldedatum: 01.01.1970 Beiträge: 312655
|
Verfasst am: Di Sep 19, 2006 1:14 pm Titel: Case vs if |
|
|
Grüezi Michael
Michael Zimmermann schrieb am 19.09.2006
> Thomas Ramel:
>> Hier ein Beispiel, das deinen Bedingungen entspricht; mir
>> persönlich gefällt der Select-Case-Block besser:
>>
> Da hast Du der If-Variante aber bezüglich Performance
> ein erhebliches Handicap aufgebürdet. Das ist unfair. ;-)
Irgendwie muss ich doch mein subjektives Empfinden untermauern ;-)
> Bei Deinem Beispiel muß ActiveCell.Value sechsmal
> ausgelesen werden. Mit einer Variablen geht das auch
> mit einem Mal:
>
> Dim z as Long
> z = ActiveCell.Value
....womit Du natürlich recht hast.
Das Beispiel war dahingehend auch nicht 'optimiert'. Ich denke die
wenigsten User werden dies dann auch tun.
> 'Da Du in der Select-Case-Variante weder eine Prüfung auf
> 'den Wertebeeich noch einen Case Else vorgesehen hast,
> 'unterstelle ich mal, daß die Werte den Bereich 0 - 30
> 'sicher nicht verlassen.
Das ist nur eine Annahme; das ursprüngliche Posting ging darauf auch nicht
näher ein.
> If z < 11 _
> Then
> Msgox "Erstens"
> Else
> If z < 21 _
> Then
> Msgbox "Zweitens"
> Else
> Msgbox "Dritens"
> End If
> End If
>
> Schon reduziert sich die Anzahl der Lesevorgänge vo 6 auf 1
> und die Anzahl der Vergleiche von 6 auf 2.
Ja, das ist sehr elegant und geht sogar noch etwas kompakter:
If z < 11 Then
MsgBox "Erstens"
ElseIf z < 21 Then
MsgBox "Zweitens"
Else
MsgBox "Dritens"
End If
> Ein solches If-Konstrukt ist dann i. d. R. schneller als
> Select-Case.
> Eine ebenfalls sehr flotte Variante ist das böse GoTo
(p)öse, das; sehr (p)öse! ;-)
> If z<11 Then Msgox "Erstens": Goto Weiter
> If z<21 Then Msgox "Zweitens": Goto Weiter
> Msgox "Drittens"
> Weiter:
>
> Aber - und da ist Dir volkommen zuzustimmen - am besten
> lesbar ist sicher das Select-Case.
Danke :-)
> Bei allen Varianten kann übrigens das durchschnittliche
> Laufzeitverhalten verbessert werden, wenn man den
> wahrscheinlichsten Fall zuerst prüft.
Ja, dieser grundsätzliche Grundsatz ist hier natürlich ebenfalls anzuwenden
:-)
Mit freundlichen Grüssen
Thomas Ramel ( [at] work)
--
- MVP für Microsoft-Excel -
[Win XP Pro SP-2 / xl2003 SP-1]
Microsoft Excel - Die ExpertenTipps tinyurl.com/cmned
.
|
|
| Nach oben |
|
 |
Michael Zimmermann
Anmeldedatum: 01.01.1970 Beiträge: 2944
|
Verfasst am: Di Sep 19, 2006 2:26 pm Titel: Case vs if |
|
|
Hallo!
Thomas Ramel:
> > Bei Deinem Beispiel muß ActiveCell.Value sechsmal
> > ausgelesen werden. Mit einer Variablen geht das auch
> > mit einem Mal:
> >
> > Dim z as Long
> > z = ActiveCell.Value
>
> ...womit Du natürlich recht hast.
> Das Beispiel war dahingehend auch nicht 'optimiert'. Ich
> denke die wenigsten User werden dies dann auch tun.
Dann sollte man es ihnen vielleicht mal laut und deutlich
sagen:
Merksatz:
Jeder Wert einer Eigenschaft oder eines
Funktionsergebnisses und jeder Objektverweis,
der öfter als einmal gebraucht wird, ist einer
typstrengen Variablen zuzuweisen.
Gruß aus Mainz
Michael
.
|
|
| Nach oben |
|
 |
Michael Zimmermann
Anmeldedatum: 01.01.1970 Beiträge: 2944
|
Verfasst am: Di Sep 19, 2006 2:27 pm Titel: Case vs if |
|
|
Hallo!
bplumhoff [at] gmail.com:
> richtig. Dann ist If doppelt so schnell wie Case.
Gleich so viel? Sieh an.
Gruß aus Mainz
Michael
.
|
|
| Nach oben |
|
 |
|