Seite 1 von 1

Abbruch bei Multiplikation mit 0, so wie bei AND und False ?

Verfasst: 16.10.2010 16:35
von STARGÅTE
Tachchen,

wie "wir" inzwischen wissen, bricht eine Logische Aussage mit And bei einem False sofort ab!
Das ist natürlich eine sehr gute Optimierung, man sollte nur aufpassen, dass man Sachen wie:
If Value And ReadFile(#File, FileName$)
vermeidet, da hier ReadFile nicht ausgeführt wird, wenn Value = 0 ist!
Ähnliches bei Or sobald ein True auftaucht!

Nun würde ich so eine Optimierung auch gerne bei folgender Sache haben: Multiplikation mit 0
Dadurch könnte man ein If sparen, welches abfragt ob etwas Wahr ist, indem man einfach zuerst diese Variable schreib die u.u. 0 wird, und dann die ganze Rechung nicht gerechnet wird, andernfalls wird alles gerechnet.

Code: Alles auswählen

Debug "==="
If Test() And Test() And 0 : EndIf
Debug "---"
If Test() And 0 And Test() : EndIf
Debug "---"
If 0 And Test() And Test() : EndIf
Debug "==="
Ergebnis = Test()*Test()*0
Debug "---"
Ergebnis = Test()*0*Test()
Debug "---"
Ergebnis = 0*Test()*Test()
Debug "==="
Hier sollte bei 0*Test()*Test() eben auch Test() nicht mehr ausgeführt werden.

Re: Abbruch bei Multiplikation mit 0, so wie bei AND und Fal

Verfasst: 17.10.2010 01:27
von Batze
Da fehlt in PB irgendwie dieser hübsche Ternäre Operator (und richtige Logikbehandlung)

Dann ginge das mit Einem Makro, so oder so ähnlich:

Code: Alles auswählen

Macro MUL(A, B)   ; Sowas müsste gehen
  ( ((A = 0) ? (0) : (A*B) )  
EndMacro


Ergebnis = MUL(0,Test()*Test())  ; Würde 0 Zurückgeben und Test() nicht ausführen
Ergebnis = 0*Test()*Test()     ; Würde 0 Zurückgeben und Test() 2x ausführen
Wenn dann Makro Noch sowas wie

Code: Alles auswählen

Macro #A MUL #B
erlauben würde, sähe das sogar ganz OK aus.


Edit: Auf was besseres als das bin ich jetzt nicht gekommen:

Code: Alles auswählen

Macro MUL(A, B)   ; Sowas müsste gehen
  (  (A <> 0) And (A*B)  )
EndMacro

Procedure Test()
  Static C.i
  C + 1
  Debug "Test "+Str(C)
  ProcedureReturn 5
EndProcedure

Ergebnis = MUL(2,Test()*Test())  ; Wird 1 (nicht 50) zurückgeben und Test() 2x ausführen
Debug Ergebnis
Ergebnis = MUL(0,Test()*Test())  ; Wird 0 Zurückgeben und Test() nicht ausführen
Debug Ergebnis
Ergebnis = 0*Test()*Test()       ; Wird 0 Zurückgeben und Test() 2x ausführen
Debug Ergebnis

Re: Abbruch bei Multiplikation mit 0, so wie bei AND und Fal

Verfasst: 17.10.2010 14:50
von GPI
STARGÅTE hat geschrieben:Tachchen,

wie "wir" inzwischen wissen, bricht eine Logische Aussage mit And bei einem False sofort ab!
Das ist natürlich eine sehr gute Optimierung, man sollte nur aufpassen, dass man Sachen wie:
If Value And ReadFile(#File, FileName$)
vermeidet, da hier ReadFile nicht ausgeführt wird, wenn Value = 0 ist!
Ähnliches bei Or sobald ein True auftaucht!
Ist das Dokumentiert, oder ists Zufällig so.

Ich würde sowas vermeiden. Vorallen weil ich eh meist versuche mit #pb_any zu arbeiten, weil es am wenigsten Probleme bereitet.

Übrigens genauso gefährlich ist der Debug-Befehl. Hier sollte man auch nie Prozeduren drüber aufrufen, die unbedingt erfolgen müssen, weil die nur mit einen Debugger ausgeführt werden

Also

Code: Alles auswählen

debug HauptFensterOeffnen()
ist absolut Böse!
besser ist

Code: Alles auswählen

tmp=HauptFensterOeffnen()
debug tmp
gleiches würde ich bei solchen IF-Abfragen machen.

Re: Abbruch bei Multiplikation mit 0, so wie bei AND und Fal

Verfasst: 17.10.2010 15:55
von PMV
GPI hat geschrieben:Ist das Dokumentiert, oder ists Zufällig so.
Wenns dokumentiert ist, dann vermultich gut versteckt :lol:
Ich weis nur so viel, das es bereits von Fred/ Freak bestätigt wurde bei einer diskusion darüber.
Ich hab aber keine Ahnung wann das war oder wo.

Im übrigen verwende ich (und ich glaub viele andere auch) diese Verhalten gerade um
unnötige Prozeduraufrufe zu vermeiden. Hatte sogar fälle, wo es wichtig war, das
eine Prozedur nicht aufgerufen wurde, wenn der vorherige Ausdruck nicht "richtig" war.

MFG PMV

Re: Abbruch bei Multiplikation mit 0, so wie bei AND und Fal

Verfasst: 17.10.2010 15:57
von GPI
Würd ich mir abgewöhnen. Wenns nicht dokumentiert ist, dann kann sich das jederzeit mal ändern (ok, hätte es sich auch so ;) )

Re: Abbruch bei Multiplikation mit 0, so wie bei AND und Fal

Verfasst: 17.10.2010 16:14
von STARGÅTE
Ich verwende es immer wenn ich mit Pointern arbeite und deren Inhalt abfragen will:

Code: Alles auswählen

If *Pointer And *Pointer\Value = 10
So kommt es nicht zum IMA, wenn der Pointer doch mal 0 ist.

Ich finds einfach schöner als:

Code: Alles auswählen

If *Pointer 
  If *Pointer\Value = 10
@GPI: (ok, hätte es sich auch so)
Eben, die Use...() Befehle wurde auch einfach irgendwann rausgenommen und lieber ein zusätzlicher Parameter in den andere Prozeduren eingeaut ...

Also ich werde die Sache mit AND auf jedefall weiterhin nutzen, weil es verschachtelte Ifs erspart, und durch den Abbruch genauso schnell ist.

Re: Abbruch bei Multiplikation mit 0, so wie bei AND und Fal

Verfasst: 17.10.2010 19:12
von Batze
Das mit dem If kenne ich aber aus vielen Programmiersprachen. Und bei Pointern benutze ich das auch häufig mit Reihenfolge. Das sollte man dokumentieren und gut ist.

Re: Abbruch bei Multiplikation mit 0, so wie bei AND und Fal

Verfasst: 18.10.2010 00:45
von PMV
Es ist eine Optimierungsgeschichte, weshalb es so ist, wie es ist.
Und da PB einfach und optimiert sein will (mehr oder weniger :lol: ),
wäre es sehr komisch, wenn es sich doch ändern würde. :wink: Und
nur weil es noch keiner gefunden hat, heißt das ja nicht, das es nicht
doch irgend wo in der Hilfe steht. :mrgreen:

Ich glaub, genau so eine Diskussion gabs schon mal vor langer Zeit,
und dann hat Freak mal was dazu gesagt und gut war. <)

MFG PMV

Re: Abbruch bei Multiplikation mit 0, so wie bei AND und Fal

Verfasst: 18.10.2010 04:30
von GPI
STARGÅTE hat geschrieben:Dadurch könnte man ein If sparen, welches abfragt ob etwas Wahr ist, indem man einfach zuerst diese Variable schreib die u.u. 0 wird, und dann die ganze Rechung nicht gerechnet wird, andernfalls wird alles gerechnet.
Was mir gerade auffällt. Klar würdest du ein IF sparen, dafür werden aber alle Berechnungen langsamer. Man muß nun nämlich für alle Operationen intern überprüfen, welchen Wert die einzelnen Teile haben, anstatt das man einfach berechnet. In Endeffekt wird damit dann jedes Programm ein Stück langsamer.

Du sparst dir in deinen Code ein IF, dafür werden aber intern in Assemblercode mehrere Hinzugefügt.

Das dürfte in Endeffekt keine Optimierung, sondern das genaue Gegenteil sein.

Re: Abbruch bei Multiplikation mit 0, so wie bei AND und Fal

Verfasst: 18.10.2010 20:07
von marco2007
PMV hat geschrieben:Ich glaub, genau so eine Diskussion gabs schon mal vor langer Zeit,
und dann hat Freak mal was dazu gesagt und gut war. <)
Meinst Du das?
http://www.purebasic.fr/english/viewtop ... 87#p275787