"OR" oder "|" *gelöst*
"OR" oder "|" *gelöst*
Wie schaut's, weiß jemand was schneller ist? Das "OR" oder das bitweise Or "|"?
Ich denke mal das macht kaum 'nen Unterschied, aber wie sieht das genau aus?
Ich denke mal das macht kaum 'nen Unterschied, aber wie sieht das genau aus?
Zuletzt geändert von Regenduft am 01.04.2008 21:29, insgesamt 1-mal geändert.
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
-
- Beiträge: 17389
- Registriert: 10.11.2004 03:22
Or ist die logische verknüpfung für Ausdrücke, | die bitweise für Zahlen.
beides solltest du besser nicht durcheinander werfen.
alsofunktioniert, aber liefert dir unvorhersagbare ergebnisse.
abenso lieferteinfach $8400, wie es sein soll,
aber was beirauskommt, hab ich noch nicht ausprobiert, auf die idee bin ich noch nicht gekommen.
beides solltest du besser nicht durcheinander werfen.
also
Code: Alles auswählen
If a=1 Or b=2
Code: Alles auswählen
If a=1 | b=2
abenso liefert
Code: Alles auswählen
$8000 | $0400
aber was bei
Code: Alles auswählen
$8000 Or $0400
Zuletzt geändert von Kaeru Gaman am 01.04.2008 18:01, insgesamt 1-mal geändert.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Der Weise weiß, dass er ein Narr ist.
Danke für die flotte Antwort, aber...
Das "Or" und "|" anders arbeiten und wie sie arbeiten ist mir schon klar:
"Or" arbeitet mit True (nicht Null) und False (Null).
"|" arbeitet Bitweise.
Manchmal kann man aber "gleich verwertbare" Ergebnisse erziehlen!
Hier ein Beispiel:
Mit Variablen funzt das ja natürlich auch!
Also: Was ist jetzt jeweils schneller?
@ Andreas_S: Ich habe leider keine Ahnung wie ich die Geschwindigkeit am besten teste...
Das "Or" und "|" anders arbeiten und wie sie arbeiten ist mir schon klar:
"Or" arbeitet mit True (nicht Null) und False (Null).
"|" arbeitet Bitweise.
Manchmal kann man aber "gleich verwertbare" Ergebnisse erziehlen!
Hier ein Beispiel:
Code: Alles auswählen
; === TEST NR.1 =======
If %00 Or %01
Debug "Check 1 -> OR"
Else
Debug "WTF?"
EndIf
If %00 | %01
Debug "Check 1 -> |"
Else
Debug "WTF?"
EndIf
Debug ""
; === TEST NR.2 =======
If %00 Or %00
Debug "WTF?"
Else
Debug "Check 2 -> OR"
EndIf
If %00 | %00
Debug "WTF?"
Else
Debug "Check 2 -> |"
EndIf
Debug ""
; === TEST NR.3 =======
If %01 Or %10
Debug "Check 3 -> OR"
Else
Debug "WTF?"
EndIf
If %01 | %10
Debug "Check 3 -> |"
Else
Debug "WTF?"
EndIf
Also: Was ist jetzt jeweils schneller?
@ Andreas_S: Ich habe leider keine Ahnung wie ich die Geschwindigkeit am besten teste...
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
-
- Beiträge: 17389
- Registriert: 10.11.2004 03:22
also, wenn du fälle findest, wo du optional programmieren kannst, dann teste das ruhig mal selber aus.
für einen test setzt du ein proggi auf, wo du NUR DIESE operation
zig-tausend-mal durchführst in einer einfachen schleife,
und vorher den Wert von ElapsedMilliseconds() notierst,
und nachher die differenz ausgibst.
dafür musst du aber den debugger abgeschaltet haben beim durchlauf,
sonst hat das ergebnis keine aussagekraft.
für einen test setzt du ein proggi auf, wo du NUR DIESE operation
zig-tausend-mal durchführst in einer einfachen schleife,
und vorher den Wert von ElapsedMilliseconds() notierst,
und nachher die differenz ausgibst.
dafür musst du aber den debugger abgeschaltet haben beim durchlauf,
sonst hat das ergebnis keine aussagekraft.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Der Weise weiß, dass er ein Narr ist.
- NicTheQuick
- Ein Admin
- Beiträge: 8809
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
Eigentlich ganz einfach.
Wenn hier a <> 0 ist, gehts direkt weiter mit c = 1 und b wird nicht mehr beachtet.
Wenn a = 0 ist, wird geprüft, ob b <> 0 ist und wenn ja geht es weiter mit c = 1; wenn nicht, geht es weiter mit c = 2.
Hier werden a und b in zwei Register gelesen, dann wird das bitweise Oder
angewendet und dann wird mittels CMP überprüft, ob das Ergebnis
ungleich Null ist. Wenn ja, geht es mit c = 1 weiter, sonst mit c = 2.
Zusammenfassung:
Wenn man weiß, dass a statistisch öfter ungleich Null ist als b, schreibt
man 'If a Or b', sonst 'If b Or a'.
Falls im Code statt a und b Funktionen stehen, die auf jeden Fall
aufgerufen werden müssen, weil sie womöglich noch global etwas ändern,
schreibt man entweder 'If Funktion1() | Funktion2()', weil dann sicher
beide aufgerufen werden, auch wenn 'Funktion1()' Null ist, oder man
schreibt das Ergebnis der zweiten Funktion in eine Hilfsvariable vor der If-Zeile ('tmp = Funktion2() : If Funktion1() Or tmp'), was natürlich nur
sinnvoll ist, wenn 'Funktion2()' auch vor 'Funktion1()' aufgerufen werden
darf. Wenn die Reihenfolge der Funktionsaufrufe wichtig ist, braucht man
natürlich zwei Hilfsvariablen.
Die Möglichkeit 'If a | b' ist also hinfällig, da langsamer.
Zum Überblick nochmal ein Code und der passende ASM-Ausschnitt:
Und zur Verdeutlichung nochmal das mit den Funktionsaufrufen:
Code: Alles auswählen
If a Or b
c = 1
Else
c = 2
EndIf
Wenn a = 0 ist, wird geprüft, ob b <> 0 ist und wenn ja geht es weiter mit c = 1; wenn nicht, geht es weiter mit c = 2.
Code: Alles auswählen
If a | b
c = 1
Else
c = 2
Endif
angewendet und dann wird mittels CMP überprüft, ob das Ergebnis
ungleich Null ist. Wenn ja, geht es mit c = 1 weiter, sonst mit c = 2.
Zusammenfassung:
Wenn man weiß, dass a statistisch öfter ungleich Null ist als b, schreibt
man 'If a Or b', sonst 'If b Or a'.
Falls im Code statt a und b Funktionen stehen, die auf jeden Fall
aufgerufen werden müssen, weil sie womöglich noch global etwas ändern,
schreibt man entweder 'If Funktion1() | Funktion2()', weil dann sicher
beide aufgerufen werden, auch wenn 'Funktion1()' Null ist, oder man
schreibt das Ergebnis der zweiten Funktion in eine Hilfsvariable vor der If-Zeile ('tmp = Funktion2() : If Funktion1() Or tmp'), was natürlich nur
sinnvoll ist, wenn 'Funktion2()' auch vor 'Funktion1()' aufgerufen werden
darf. Wenn die Reihenfolge der Funktionsaufrufe wichtig ist, braucht man
natürlich zwei Hilfsvariablen.
Die Möglichkeit 'If a | b' ist also hinfällig, da langsamer.
Zum Überblick nochmal ein Code und der passende ASM-Ausschnitt:
Code: Alles auswählen
a = 1
b = 2
If a Or b
c = 1
Else
c = 2
EndIf
If a | b
c = 3
Else
c = 4
EndIf
Code: Alles auswählen
; :
; a = 1
MOV dword [v_a],1
; b = 2
MOV dword [v_b],2
;
; If a Or b
CMP dword [v_a],0
JNE _AO_Ok0
CMP dword [v_b],0
JNE _AO_Ok0
JMP _AO_No0
_AO_Ok0:
MOV eax,1
JMP _AO0
_AO_No0:
XOR eax,eax
_AO0:
AND eax,eax
JE _EndIf2
; c = 1
MOV dword [v_c],1
; Else
JMP _EndIf1
_EndIf2:
; c = 2
MOV dword [v_c],2
; EndIf
_EndIf1:
;
; If a | b
MOV ebx,dword [v_a]
OR ebx,dword [v_b]
AND ebx,ebx
JE _EndIf5
; c = 3
MOV dword [v_c],3
; Else
JMP _EndIf4
_EndIf5:
; c = 4
MOV dword [v_c],4
; EndIf
_EndIf4:
Code: Alles auswählen
Global a.l, b.l
Procedure a()
Debug "a"
ProcedureReturn a
EndProcedure
Procedure b()
Debug "b"
ProcedureReturn b
EndProcedure
Debug "Mit 'Or' und a=1 und b=2:"
a = 1
b = 2
If a() Or b()
c = 1
Else
c = 2
EndIf
Debug "Mit 'Or' und a=0 und b=2:"
a = 0
b = 2
If a() Or b()
c = 1
Else
c = 2
EndIf
Debug "Mit '|' und a=0 und b=2:"
If a() | b()
c = 3
Else
c = 4
EndIf
-
- Beiträge: 17389
- Registriert: 10.11.2004 03:22
wie gesagt, je nachdem was ich "or" vergleichen will.
übersetz mir malmit nem "|", so dass es auch immer funktioniert.... 
aber danke @nic für die aufklärende ausführung.
PS:
der Ersteller hat ein Post gelöscht, auf das ich ursprünglich geantwortet hatte, nur fürs protokoll....
übersetz mir mal
Code: Alles auswählen
If XPos < CheckPos Or XPos > Checkpos + TileWidth

aber danke @nic für die aufklärende ausführung.

PS:
der Ersteller hat ein Post gelöscht, auf das ich ursprünglich geantwortet hatte, nur fürs protokoll....
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Der Weise weiß, dass er ein Narr ist.
@ NicTheQuick: Danke! Mir haben sich gerade Horizonte geöffnet!
@ Kaeru German: Sorry fürs gelöschte Post... A) hatte ich erst 'nen Denkfehler in meinem Leistungstest und B) war beim Posterstellen noch nicht die Antwort von NicTheQuick vorhanden.
Irgendwas mache ich falsch meine Posts enden irgendwie immer mit einem oops
@ Kaeru German: Sorry fürs gelöschte Post... A) hatte ich erst 'nen Denkfehler in meinem Leistungstest und B) war beim Posterstellen noch nicht die Antwort von NicTheQuick vorhanden.
Irgendwas mache ich falsch meine Posts enden irgendwie immer mit einem oops

PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
Noch zum Spaß @ Kaeru German
enstspricht (glaube ich):
...aber jetzt mache ich mich lächerlich
nicht dass der ganze Thread noch im Müll landet...
Code: Alles auswählen
If XPos < CheckPos Or XPos > Checkpos + TileWidth
Code: Alles auswählen
If (XPos < CheckPos) | (XPos > Checkpos + TileWidth)

PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
-
- Beiträge: 17389
- Registriert: 10.11.2004 03:22
du bist neu in PB, gell?
ein (Value Compare Value) ergibt nicht zwangsweise #True oder #False,
wie in anderen Hochsprachen, sondern liefert vielmehr den überlegenen Registerwert zurück.
PB kennt keine nativen Boole'sche Ausdrücke!
es gibt ein workaround in PB, nämlich ((Value Compare Value) And/Or Bool),
damit du wirklich eine Zahlenmäßig brauchbare boole'sche Auswertung deines Ausdrucks bekommst.
ein (Value Compare Value) ergibt nicht zwangsweise #True oder #False,
wie in anderen Hochsprachen, sondern liefert vielmehr den überlegenen Registerwert zurück.
PB kennt keine nativen Boole'sche Ausdrücke!
es gibt ein workaround in PB, nämlich ((Value Compare Value) And/Or Bool),
damit du wirklich eine Zahlenmäßig brauchbare boole'sche Auswertung deines Ausdrucks bekommst.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Der Weise weiß, dass er ein Narr ist.