#1 27.08.2012 07:47:04

DerPeer
GodlikeMember
Ort: Berlin
Registriert: 04.02.2005
Beiträge: 1291

Code-Optimierung

Hallo Leute!

Ich hab da ein Stück Code, der möglichst schnell ablaufen soll. Hat jemand einen Vorschlag, wie man den besser ausdrücken könnte?

Code: delphi

if bed_a then x: = x + m;
if bed_b then x: = x - m;

if not(bed_a or bed_b) then begin
  if bed_c then y: = y + m;
  if bed_d then y: = y - m;
end;


Sowas wär nicht schlecht:
X := X + Bed_A*M - Bed_B*M;

Aber das will Delphi nicht.

Danke

DerPeer

Offline

 

#2 27.08.2012 08:53:25

Gnietschow
ProMember
Ort: Berlin
Registriert: 20.06.2007
Beiträge: 237

Re: Code-Optimierung

Hi smile

Ein Boolean wird in Delphi durch einen byte repräsentiert. Der Boolean ist false wenn er 0 ist und true sonst. An sich könntest du für deine kürzere Formel casten, z.B. mit Integer(Bed_A), aber da ist nicht sichergestellt, dass was falsches rauskommt. Sicherer ist es mit der Delphimethode ord. Die gibt dir 0 wenns false ist und 1 wenns true ist zurück.

Also kannst du locker schreiben

Code:

x := x + ord(bed_a) * m - ord(bed_b) * m

Wenn nur eine Bedingung gleichzeitig wahr sein kann, könntest du auch mit aufeinanderfolgenden if...else-Blöcken arbeiten:

Code:

if bed_a then x: = x + m
else if bed_b then x: = x - m
else if bed_c then y: = y + m
else if bed_d then y: = y - m;

Aber an sich würde ich sagen, dass Optimierung auf so einem niedrigen Level meist kaum etwas bringt. Bei meinen Programmen hab ich mal stundenlang solche kleinen Passage optimiert, z.B. mit Bitshifting usw. Gebracht hat es kein einzigen Frame mehr, wobei Strukturänderungen am Programm selbst viel mehr bringen. Bessere Algorithmen und effizientere Datenstrukturen sind eher der Punkt, wo Performance zu holen ist. (bei normalen Delphicode, bei Shadercode bringen auch kleine Verbesserungen manchmal spürbare Unterschiede).

MfGnietschow


Es gibt 10 Gruppen von Menschen - die die das Binärsystem verstehen und die anderen.  :-)
Vegetarier essen meinem Essen das Essen weg ;)
-------------------------------------------------------------------------------------------------------------------
Der Community-Hub für Videospiele: gameloop.io

Offline

 

#3 27.08.2012 17:31:05

DerPeer
GodlikeMember
Ort: Berlin
Registriert: 04.02.2005
Beiträge: 1291

Re: Code-Optimierung

Hey danke sehr!

Ja ich dachte mir schon, dass das vielleicht gar nicht SO viel bringt, aber trotzdem.

Dein 2. Code ist aber nicht ganz der richtige, weil ich in meinem Code die Y-Zuweisungen auch erreichen kann, wenn Bed_A wahr ist.
Ansonsten stimmt aber: Bed_A and Bed_B = false, ebenso Bed_C and Bed_D = false!

DerPeer

Offline

 

#4 28.08.2012 08:17:04

Lotipats
UltraMember
Registriert: 17.05.2005
Beiträge: 395

Re: Code-Optimierung

Ich habe mal einen Test vorgenommen:

Code: delphi

var
  b: boolean;
  x: integer;
  x1, x2:integer;
  m: integer;
begin
  b := boolean(5);
  x := 5;
  m := 2;

  x1 := x;
  if(b)then x1 := x + m;
  x2 := x + ord(b)*m;

  writeln('x1: '+inttostr(x1)+'; x2: '+inttostr(x2));

Das Ergebnis:

Code:

x1: 7; x2: 15

Demnach scheint dein Code, Gnietschow, nicht allgemein semantisch äquivalent zu dem von DerPeer zu sein. Hast du Bedingungen unter denen er gleich ist?
Durch die Definition, die du gegeben hast - 0 ist false, alles andere true - hat der Compiler gewisse Möglichkeiten der Optimierung, er muss Dinge wie true nicht auf 1 abbilden. Auf Assemblerebene gibt es auch kein Boolean, ein OR ist beispielsweise immer bitweise. Damit kann ein "var:=true" z.B. auch zu "inc var" optimiert werden, je nach Vorbedingung.
Deshalb frage ich, ob du Bedingungen kennst, bei der ein "ord(boolean)" definitiv 1 bei true zurück gibt. Ich selber weiß beispielsweise nicht, wie der Compiler was optimiert bzw. wann es überhaupt pot. optimierungswürdig ist. Letzteres geht mit in die Frage, ob es sich bei neueren Compilern ändern könnte und damit ob der Code aufwärtskompatibel ist.

LOTIPATS

Offline

 

#5 28.08.2012 08:51:24

DragonFlyOfGold
ProMember
Ort: Berlin
Registriert: 09.11.2005
Beiträge: 139

Re: Code-Optimierung

An sich gibt es ja mehrere boolsche Typen: boolean, bytebool, wordbool und longbool. Bei den letzen drei steht in der Delphi Hilfe

Zitat:

Ein (Byte/Word/Long)Bool-Wert gilt als False, wenn seine Ordinalposition 0 ist, ansonsten als True.

und sie sind über den jeweiligen Bereich gültig den ihr Speicherbereich hergibt. Diese sind nur aus Kompatibilitätsgründen vorhanden.
Boolean an sich ist nur als

Code: delphi

type boolean = (false, true);

definiert und in der Hilfe steht

Zitat:

Ein Boolean-Wert gilt als True, wenn seine Ordinalposition 1 ist, und als False, wenn seine Ordinalposition 0 (Null) ist.

Delphi kümmert sich darum, dass dies auch eingehalten wird:

Zitat:

Ein Wert vom Typ ByteBool, LongBool oder WordBool hat den Wert True, wenn seine ordinale Position ungleich Null ist. Tritt ein derartiger Wert in einem Kontext auf, in dem ein Wert vom Typ Boolean erwartet wird, wandelt der Compiler automatisch einen Wert mit einer Ordinalposition ungleich Null in den Wert True um.

(Quelle: http://docwiki.embarcadero.com/RADStudi … ache_Typen da steht auch nochmal alles gut beschrieben über Booleans) Aber gegen nen Speichercast wie in deinem Code kann Delphi natürlich nix dagegen tun tongue
Ansonsten scheint es auch keinen wirklich 100%ig verlässliches Mapping zu geben, man kann ja immer wild im Speicher rumschreiben. Aber für normale Delphi-Anwendungen dürfte es schon gehen. Sobald man aber den Code in ne DLL packt und in anderen Umgebungen nutzen möchte, sollte man dann doch eher davon Abstand nehmen, man weiß ja nie in welcher Form man dort Booleans von der Anwendung bekommt, obwohl ich eigentlich dem Delphi-Compiler vertraue, dass der das schon ordentlich vorbereitet smile.
Um aber wirklich auf der sicheren Seite zu sein, ist wahrscheinlich das einfachste doch das if zu nehmen oder sich ne eigene Funktion zu schreiben, welche aber dann keine Geschwindigkeitsvorteile mehr bringt.

Code: delphi

function booltoint(b:boolean):integer;
begin
  if b then result:=1 else result:=0;
end;


DfoG

Beitrag geändert von DragonFlyOfGold (28.08.2012 08:51:52)

Offline

 

#6 28.08.2012 09:03:41

Gnietschow
ProMember
Ort: Berlin
Registriert: 20.06.2007
Beiträge: 237

Re: Code-Optimierung

Noch ein kleiner Nachtrag zum Sinn oder Unsinn von solchen Mikrooptimierungen:

Selbst wenn sie den Code ein wenig schneller machen, mit mathematischen Tricks oder coolen Speichermanipulationen, meist machen solche Optimierungen den Code um einiges schlechter lesbar. Vor allem wenn man ein zwei Jahre später reinschaut und sich fragt "Was hab ich den DA gemacht?!?" yikes . Je komplexer ein Programm wird (und vor allem ein Spiel), desto wichtiger wird auch die Wartbarkeit, da sich ja doch überall kleine Käfer (aka Bugs smile) einschleichen und auf den ungünstigsten Moment warten an dem sie auftauchen können. Wenn ich mir meinen Code anschaue den ich vor ein paar Jährchen geschrieben habe, graust es mir meist ein bisschen wink Keine Kommentare, teilweise nicht eingerückt, wenig klare Strukturen und eben solche "Optimierungen". Den größten Teil schreibe ich dann meist neu roll

MfGnietschow

Beitrag geändert von Gnietschow (28.08.2012 10:37:56)


Es gibt 10 Gruppen von Menschen - die die das Binärsystem verstehen und die anderen.  :-)
Vegetarier essen meinem Essen das Essen weg ;)
-------------------------------------------------------------------------------------------------------------------
Der Community-Hub für Videospiele: gameloop.io

Offline

 

#7 28.08.2012 11:22:57

DerPeer
GodlikeMember
Ort: Berlin
Registriert: 04.02.2005
Beiträge: 1291

Re: Code-Optimierung

Also erstmal danke an Alle!

@Gnietschow: Lustig, dass du gerade die Lesbarkeit ansprichst. Gestern hatte ich eine Zeile die sah so aus:

Code: delphi

if (sph1.mirror.left) or (sph1.mirror.right) then
  neupos1.x:=2*frac(pos1.x/(2*arena.xlimit)+1)*arena.xlimit;


Gemeint war das damit (ein Teil des einleitenden CodeBeispiels):

Code: delphi

if (sph1.mirror.left) then newpos1.x:=newpos1.x+2*arena.xlimit;
if (sph1.mirror.right) then newpos1.x:=newpos1.x-2*arena.xlimit;


:-) Na jedenfalls hab ich eine Weile für die frac-Zeile gegrübelt, was das eigentlich soll. Kommentare natürlich Fehlanzeige :-)

Der Code soll übrigens in meinem Asteroids-Klon die Kollisionen korrigieren, wenn die Objekte aus dem Bildschirmrand herausfliegen und auf der anderen Seite wieder hinein. Dazu muss man Fake-Positionen generieren, damit das funktioniert.

Na danke nochmal. Ich entscheide mich dann gegen eine kryptische Optimierung, deren Zeitvorteil zweifelhaft ist.

DerPeer

Offline

 

Brett Fußzeile

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson