Autor Beitrag
walter_b
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: Fr 18.07.08 18:30 
Hallo zusammen

Delphi verblüfft mich echt immer wieder aufs Neue. Und diesmal kann ich mir es echt sowas von nicht erklären, vielleicht wisst ihr ja weiter. Mich würde bloss interessieren, wieso die eine Variante schneller ist als die andere.

Diese Variante dauert ebenfalls bei 1 Mia Durchgängen 3600ms. Der Vergleich: Len wird oben als Variable gelöscht, Len:=0 wird rausgestrichen und Len:=max(Y,Len) wird entfernt. Der Rest ist total identisch. Len wird im ganzen Programm nirgends sonst verwendet, ist noch ein Überbleibsel eines vorher durchgeführten Versuches.

Kann jemand von euch mir das erklären? Steht Delphi drauf, mehr zu tun als notwendig? :P


Zuletzt bearbeitet von walter_b am Mo 04.08.08 14:33, insgesamt 1-mal bearbeitet
Hidden
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Fr 18.07.08 20:37 
Hi,

imho ehrer Algorithmen und Optimierung, oder?

hast du schonmal die Optimierung ausgeschaltet?({$O-} {$O+})

mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
walter_b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: Fr 18.07.08 21:09 
user profile iconHidden hat folgendes geschrieben:
Hi,

imho ehrer Algorithmen und Optimierung, oder?

hast du schonmal die Optimierung ausgeschaltet?({$O-} {$O+})

mfG,


Sorry? Ich kann dir nicht folgen. Zuerst einmal: Was hatte das kleingedruckte zu bedeuten? Und welche Optimierung ausschalten? Und was ist {$0-} {$0+}? :oops: :?!?:
Timosch
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1314

Debian Squeeze, Win 7 Prof.
D7 Pers
BeitragVerfasst: Fr 18.07.08 21:42 
Das sind Compilerdirektiven, mit denen du die Optimierung ausschalten kannst.

_________________
If liberty means anything at all, it means the right to tell people what they do not want to hear. - George Orwell
walter_b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: Fr 18.07.08 21:47 
Und wo soll ich die hinsetzen? Und beide oder nur einen?
Nils:D
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 131

Debian, Win XP
Delphi 7 Arch.
BeitragVerfasst: Fr 18.07.08 21:55 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
{$0-}
procedure blubb;
begin
  ...
end;
{$0+}

Du musst die Optimierung vor der gewünschten Prozedur deaktivieren und hinterher wieder aktivieren. Compiler-Optimierungen sorgen für ein schnelleres und kleineres Programm, können daher den einen Algorithmus verschnellern, den anderen nicht, da ein gewisser Fall dort nicht gegeben sein könnte.
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Fr 18.07.08 21:58 
Das Phänomen ist doch, das der Code schneller wird, wenn man etwas weg nimmt. Was wird denn da -bitte schön- optimiert? ich tippe eher auf einen kleinen Fehler (oder eine Eigenheit) beim Übersetzen in Maschinencode. Es kann sein, das die Heuristik, die die Variablen auf Register verteilt, bei der Variante 1 einfach besser funktioniert, als bei #2.

_________________
Na denn, dann. Bis dann, denn.
walter_b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: Fr 18.07.08 22:11 
user profile iconNils:D hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
{$0-}
procedure blubb;
begin
  ...
end;
{$0+}

Du musst die Optimierung vor der gewünschten Prozedur deaktivieren und hinterher wieder aktivieren. Compiler-Optimierungen sorgen für ein schnelleres und kleineres Programm, können daher den einen Algorithmus verschnellern, den anderen nicht, da ein gewisser Fall dort nicht gegeben sein könnte.


Invalid Compiler directive: '$0'

Naja, ist ja eigentlich auch egal. Ich lasse es einfach drin, da es so um das doppelte schneller ist. Warum sich mit weniger zufrieden geben? ;) (Auch wenn jeder, der den Code anschaut, denken wird, dass ich spinne :D)
Nils:D
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 131

Debian, Win XP
Delphi 7 Arch.
BeitragVerfasst: Fr 18.07.08 22:19 
Hm, dürfte eigentlich funktionieren. Aber für die Zukunft noch eine Empfehlung: Schreibe ein Kommentar hin, warum du es so gemacht hast und dass diese Stelle eventuell bei einem anderen Compiler nicht schneller oder sogar leicht langsamer sein dürfte. Es kann nämlich gut sein, dass ein neuerer/älterer Compiler das anders kompiliert.
Guenther A.
Hält's aus hier
Beiträge: 5



BeitragVerfasst: So 20.07.08 00:25 
Titel: Ist max eine externe Function?
Ist die max-Function eine exteren Function, das würde einiges erklären. Jedenfalls kenn mein Delphi-7 die Funktion nicht. Die Befehle in der Schleife sind sehr schnell, da hätte der Aufruf von max schon mit den erforderlichen Stack-Operationen einen erhebliche Anteil.

Tipp: Sie Die einmal das CPU-Fenster für den Code an (Breakpoint setzen). Auc wenn Du denn Assembler-Code nicht genau verstehst, so gibt es doch eine Eindruck, was passiert. F7 funktioniert auch da.

Gruß Guenther
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: So 20.07.08 00:49 
user profile iconwalter_b hat folgendes geschrieben:
[Invalid Compiler directive: '$0'

Nicht Null, O wie Optimization.

user profile iconGuenther A. hat folgendes geschrieben:
Jedenfalls kenn mein Delphi-7 die Funktion nicht.

ausblenden Delphi-Quelltext
1:
uses Math;					

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 20.07.08 10:04 
Hast du die zwei Prozeduren auch wirklich unter exakt identischen Voraussetzungen laufen gelassen?
walter_b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: So 20.07.08 12:56 
user profile icondelfiphan hat folgendes geschrieben:
Hast du die zwei Prozeduren auch wirklich unter exakt identischen Voraussetzungen laufen gelassen?


Ja, habe ich!


Und da es gleich zum Thema passt, langsam habe ich echt das Gefühl, dass Delphi masochistisch veranlagt ist. Schaut euch mal dies an:

Variabeln:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var  
  X, Y:  Integer;
  Wort:  String;     // Direkt String
  fChar: PChar;
  binlm, bigpass, endhash: string;



Schnellere Variante (136 Sekunden bei 1 Mia Durchgängen):
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
  bigpass:=Copy(AnsiUpperCase(Wort)+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0,0,14);
  anf:=parityshift(Copy(bigpass,0,7));
  ende:=Copy(bigpass,8,7);
  ende:=parityshift2(ende);
  alpha:=DecodeText('KGS!@#$%',anf);
  alpha:=HexStrToString(alpha);
  beta:=DecodeText('KGS!@#$%',ende);
  beta:=HexStrToString(beta);
  binlm:=alpha+beta;
  endhash:=StringToHexStr(binlm);


Langsamere Variante (141 Sekunden bei 1 Mia Durchgängen):
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
  bigpass:=Copy(AnsiUpperCase(Wort)+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0+#0,0,14);
  anf:=parityshift(Copy(bigpass,0,7));
  ende:=Copy(bigpass,8,7);
  ende:=parityshift2(ende);
  alpha:=DecodeText('KGS!@#$%',anf);
  beta:=DecodeText('KGS!@#$%',ende);
  binlm:=alpha+beta;



Unterschied: Bei der oberen Variante wird sinnloserweise zuerst die Hex-Darstellung zu einem String umgewandelt, und nachher wieder zurück. Das Ergebnis ist bei beiden total identisch.

Hier noch die Umwandlungsfunktion:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function HexStrToString(const value:string):string;
begin
   SetLength(Result, Length(value) div 2);
   if Length(value) > 0 then
      HexToBin(PChar(value), PChar(Result), Length(value));
end;

function StringToHexStr(const value:string):string;
begin
   SetLength(Result, Length(value)*2);
   if Length(value) > 0 then
      BinToHex(PChar(value), PChar(Result), Length(value));
end;



Hat jemand für das eine Erklärung? Hier kann es ja nicht mehr wirklich die Begründung sein, dass die zusätzliche Variabel alles vielleicht ein bisschen schneller macht. Bin mal gespannt auf eure Vermutungen/Erklärungen.


Edit: anf, ende, alpha, beta, endhash binlm wurde alles initialisiert und mit der richtigen Länge definiert.


Zuletzt bearbeitet von walter_b am So 20.07.08 18:30, insgesamt 2-mal bearbeitet
Grenzgaenger
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 20.07.08 13:05 
du weisst ja auch, dass die beiden Varianten was ganz anderes machen :roll:
walter_b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: So 20.07.08 13:13 
user profile iconGrenzgaenger hat folgendes geschrieben:
du weisst ja auch, dass die beiden Varianten was ganz anderes machen :roll:


Ehrlichgesagt: Nein, das weiss ich nicht. Zuerst wird ja der Hash erstellt, welcher dann in zwei Teilen vorhanden ist, zwar in anf und in ende. Danach wird bei der schnelleren Variante das ganze in zwei Strings umgeformt (also aus dem Hexidezimalsystem), zusammengesetzt und wieder ins Hexidezimalsystem zurückverwandelt. Bei der langsameren Variante werden die beiden Teile zusammengesetzt und fertig. Wieso ist es schneller, wenn ich zuerst sinnlos umwandle und wieder zurückwandle? Das Ergebnis ist nämlich total identisch.
Hidden
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: So 20.07.08 13:47 
Hi,

Ich hab das ganze mal gehighlighted:

ausblenden Schnellere Variante (136 Sekunden bei 1 Mia Durchgängen):
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
bigpass := Copy(AnsiUpperCase(Wort)+#0+#0+#0+#0+#0+#0
         +#0+#0+#0+#0+#0+#0+#0+#0,0,14);
anf := ParityShift(Copy(Bigpass, 07));
ende := Copy(Bigpass, 87);
ende := ParityShift(ende);
alpha := DecodeText('KGS!@#$%', anf);
alpha := HexStrToString(alpha);
beta := DecodeText('KGS!@#$%', ende);
beta := HexStrToString(beta);
binlm := alpha + beta;
endhash := StringToHexStr(binlm);


ausblenden Langsamere Variante (141 Sekunden bei 1 Mia Durchgängen):
1:
2:
3:
4:
5:
6:
7:
8:
bigpass := Copy(AnsiUpperCase(Wort)+#0+#0+#0+#0+#0+#0
         +#0+#0+#0+#0+#0+#0+#0+#0,0,14);
anf := ParityShift(Copy(Bigpass, 07));
ende := Copy(Bigpass, 87);
ende := ParityShift(ende);
alpha := DecodeText('KGS!@#$%', anf);
beta := DecodeText('KGS!@#$%', ende);
binlm := alpha + beta;


Ist die Deklaration von alpha/ß verschieden? imho hängst du einmal einen String an einen anderen an und einmal addierst du zwei Zahlenwerte..

Sollte es sich beide male um Strings handeln, ist die HexString-Darstellung wahrscheinlich einfach kürzer und deshalb dauert das anhängen weniger lang.

Hab jetzt aber auch gerade nicht die Zeit, mich tiefer einzuarbeiten. Schätze mal, dass ich mich oben verguckt habe mit einmal Strings aneinanderhängen und einmal zwei Zahlen addieren.

E: DIe Deklaration von a/ß fehlt ja auch :roll:
E2: Mit HexToBin fällt wohl die Kürzerer-String-Theorie weg^^

mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)


Zuletzt bearbeitet von Hidden am So 20.07.08 13:56, insgesamt 3-mal bearbeitet
walter_b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: So 20.07.08 13:51 
Nein, sind beides Mal zwei Strings. Sonst würde es ja auch nicht das selbe Ergebnis geben, wenn zwei Zahlenwerte zusammengerechnet werden würden.

Also sollte ich ab jetzt jedes mal, wenn ich zwei Strings zusammenfügen will, die zuerst umwandeln und dann wieder zurück? :D
Hidden
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: So 20.07.08 13:55 
Hi,

Imho liegt es an deinen #0.. kA, was damit genau passiert. hab gerade kein Delphi da.. Könntest du mal das Ergebnis der HexStringToString ausgeben lassen?

mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
Grenzgaenger
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 20.07.08 14:10 
wo kommt denn hier das selbe raus?

V1: binlm := HexStrToString(DecodeText('KGS!@#$%', anf)) + HexStrToString(DecodeText('KGS!@#$%', ende));

V2: binlm :=  DecodeText('KGS!@#$%', anf) + DecodeText('KGS!@#$%', ende);

denke doch, dass das was anderes ist, oder? :roll:


Zuletzt bearbeitet von Grenzgaenger am So 20.07.08 14:11, insgesamt 2-mal bearbeitet
walter_b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: So 20.07.08 14:10 
Nach dem DecodeText ist anf '695109ab020e401c' und ende 'aad3b435b51404ee'. Nach dem HexStrtoString sind beide Werte ziemlich hässlich, sehr unschöne Sonerzeichen. Nach dem alpha+beta sind die beiden "hässlichen" Strings einfach aneinander gehängt, und nach StringtoHexStr ist der Endstring '695109ab020e401caad3b435b51404ee'. Also einfach anf und ende aneinander gehängt.