Autor |
Beitrag |
walter_b
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: 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? 
Zuletzt bearbeitet von walter_b am Mo 04.08.08 14:33, insgesamt 1-mal bearbeitet
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: 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 
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: Fr 18.07.08 21:09
|
|
Timosch
      
Beiträge: 1314
Debian Squeeze, Win 7 Prof.
D7 Pers
|
Verfasst: 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 
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: Fr 18.07.08 21:47
Und wo soll ich die hinsetzen? Und beide oder nur einen?
|
|
Nils:D
      
Beiträge: 131
Debian, Win XP
Delphi 7 Arch.
|
Verfasst: Fr 18.07.08 21:55
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
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: 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 
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: Fr 18.07.08 22:11
Nils:D hat folgendes geschrieben: | 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  )
|
|
Nils:D
      
Beiträge: 131
Debian, Win XP
Delphi 7 Arch.
|
Verfasst: 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
|
Verfasst: 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
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: So 20.07.08 00:49
_________________ "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
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: So 20.07.08 10:04
Hast du die zwei Prozeduren auch wirklich unter exakt identischen Voraussetzungen laufen gelassen?
|
|
walter_b 
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: So 20.07.08 12:56
delfiphan 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:
Delphi-Quelltext 1: 2: 3: 4: 5:
| var X, Y: Integer; Wort: String; fChar: PChar; binlm, bigpass, endhash: string; |
Schnellere Variante (136 Sekunden bei 1 Mia Durchgängen):
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):
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:
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
|
Verfasst: So 20.07.08 13:05
du weisst ja auch, dass die beiden Varianten was ganz anderes machen 
|
|
walter_b 
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: So 20.07.08 13:13
Grenzgaenger hat folgendes geschrieben: | du weisst ja auch, dass die beiden Varianten was ganz anderes machen  |
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
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: So 20.07.08 13:47
Hi,
Ich hab das ganze mal gehighlighted:
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, 0, 7)); ende := Copy(Bigpass, 8, 7); ende := ParityShift(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): 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, 0, 7)); ende := Copy(Bigpass, 8, 7); 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
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 
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: 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? 
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: 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
|
Verfasst: 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? 
Zuletzt bearbeitet von Grenzgaenger am So 20.07.08 14:11, insgesamt 2-mal bearbeitet
|
|
walter_b 
      
Beiträge: 135
Windows Vista/XP
Delphi 6
|
Verfasst: 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.
|
|
|