![]() |
PosEx? Oder doch lieber Pos? - Performance!
Ich habe heute eine sehr interessante Entdeckung gemacht. Ihr habt sie wahrscheinlich schon vor langer Zeit gemacht, ich leider erst eben.
Ich habe entdeckt, dass PosEx() viel schneller arbeitet als Pos(). 1.000.000 Mal
Delphi-Quellcode:
werden bei mir innerhalb von circa 570 Millisekunden abgearbeitet.
if Pos(IrgendeinString, UndNochIrgendeinString) > 1
Dasselbe mit PosEx jedoch innerhalb von circa 140 Millisekunden. Sollte man demnach lieber PosEx() benutzen statt Pos()? |
AW: PosEx? Oder doch lieber Pos? - Performance!
Machst du in deinem Programm wirklich 1 Mio mal hintereinander Posex oder auf mehrere Jahrzehnte verteilt? Mir persönlich ist das eigentlich immer ziemlich egal ob irgendein Wartevorgang für ein "Ich klicke auf irgendwas" nun 30 oder 31 Millisekunden dauert.
Und ja, technisch gesehen ist dieser Beitrag nicht hilfreich. |
AW: PosEx? Oder doch lieber Pos? - Performance!
Selbstverständlich mache ich das nicht. Aber ich fand es schon interessant, dass PosEx() um den Faktor 3 schneller ist.
|
AW: PosEx? Oder doch lieber Pos? - Performance!
was gibst du denn bei PosEx als Offset an?
|
AW: PosEx? Oder doch lieber Pos? - Performance!
Also eine Millionen mal dauert Posex bei mir 6 Millisekunden und 7 Millisekunden für "Pos".
Delphi-Quellcode:
program Project11;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.AnsiStrings, System.Diagnostics; const s1 = 'Hallo Welt'; s2 = 'lo'; count = 1E6; //{$Define Posex} var times: Integer; result: Integer; stopWatch: TStopwatch; begin times := 0; stopWatch := TStopwatch.StartNew(); repeat {$If Defined(Posex)} result := System.AnsiStrings.PosEx(s2, s1); {$Else} result := System.Pos(s2, s1); {$EndIf} Inc(times); until (times = count); stopWatch.Stop(); Writeln( stopWatch.ElapsedMilliseconds ); readln; end. Wenn du in die Implementation schaust wirst du sehen dass PosEx nichts anderes tut als Pos aufzurufen. PosEx hat aber noch eine "inline"-Direktive. Ich kann kein Assembler lesen, könnte mir aber vorstellen dass der Compiler dann das komplette "Pos" inlined sodass er sich einen Sprung spart. Könnte das mal jemand prüfen? |
AW: PosEx? Oder doch lieber Pos? - Performance!
Zitat:
- Wir haben nicht dieselbe Delphi-Version - Wir haben nicht denselben Computer :lol: |
AW: PosEx? Oder doch lieber Pos? - Performance!
Zitat:
Gruß K-H |
AW: PosEx? Oder doch lieber Pos? - Performance!
XE2 benutze ich.
|
AW: PosEx? Oder doch lieber Pos? - Performance!
In den neuen Delphi Versionen scheint
Delphi-Quellcode:
nur noch ein Alias für
PosEx
Delphi-Quellcode:
zu sein. Früher hatte
Pos
Delphi-Quellcode:
noch nicht den optionalen
Pos
Delphi-Quellcode:
Parameter, deshalb brauchte man eine seperate
Offset
Delphi-Quellcode:
Funktion.
PosEx
|
AW: PosEx? Oder doch lieber Pos? - Performance!
Ich hab mal dem Code von Günther in XE und Berlin getestet und muss sagen, in XE (und vermutlich dann auch XE2) schien Pos enorm langsam zu sein und nicht etwa PosEx schneller (im Vergleich zu den Ergebnissen in Berlin)
P.S. Ich hab natürlich die Unicode Version von PosEx aus StrUtils verwendet und nicht die AnsiString Version - wir wollen ja nicht Äpfel und Birnen vergleichen, gell? :stupid: |
AW: PosEx? Oder doch lieber Pos? - Performance!
Zitat:
Du sagst, Pos scheint enorm langsam zu sein, und dass PosEx nicht schneller ist. Was ist denn nun schneller gewesen bei deinem Test :-D |
AW: PosEx? Oder doch lieber Pos? - Performance!
Zitat:
Zitat:
In Spring haben wir übrigens folgenden Code:
Delphi-Quellcode:
:mrgreen:
{$IFNDEF DELPHIXE3_UP}
function Pos(const SubStr, Str: UnicodeString; Offset: Integer): Integer; asm jmp PosEx end; {$ENDIF} |
AW: PosEx? Oder doch lieber Pos? - Performance!
Ok interessant.
Zur Frage, welchen offSet ich bei PosEx verwenden würde: ich benutze gar keinen. Ich gebe keinen an, also gilt 1. |
AW: PosEx? Oder doch lieber Pos? - Performance!
Ich habe Günthers Code mit kleinen Abweichungen (TStopwatch ist unbekannt)
durch D2006 und D7 gejagt D2006 pos: 0,024 posex:0,024 s D7 pos:0,152 posex 0,147 s und hier der code:
Delphi-Quellcode:
Packt man noch 40 Leerzeichen an den Anfang von S1, dann ist das Verhältnis 0,201/0,198.
program Project2;
{$APPTYPE CONSOLE} {$R *.res} uses SysUtils ,strutils ; const s1 = 'Hallo Welt'; s2 = 'lo'; count = 2E6; //{$Define Posex} var times: Integer; result: Integer; sz,ez : tdatetime; begin times := 0; sz:=now; repeat {$If Defined(Posex)} result := PosEx(s2, s1); {$Else} result := System.Pos(s2, s1); {$IFEnd} Inc(times); until (times = count); ez:=now; Writeln(formatdatetime('HH:MM:SS,zz', ez-sz) ); readln; end. Es scheint wohl wieder zu gelten: "wer misst, misst Mist" Gruß K-H |
AW: PosEx? Oder doch lieber Pos? - Performance!
Beides Pre-Unicode Versionen, somit: Äpfel <> Birnen
Außerdem ist mit Now messen auch Tinnef. |
AW: PosEx? Oder doch lieber Pos? - Performance!
In beiden Fällen werden Ansis verglichen, das sind Äpfel oder Birnen aus dem gleichen Korb.
Die Ausgangsfrage war gibt es einen Unterschied zwischen pos und posex, was implizit "beim gleichen Compiler beinhaltet"? Und im Rahmen der Meßgenauigkeit kann ich Dir sagen für D2006 und D7 gilt nein. Gruß K-H |
AW: PosEx? Oder doch lieber Pos? - Performance!
Also "früher" gab es im Delphi kein PoSex, darum brauchte man eine eigene/fremde Implementation. (bis um Delphi 6/7 rum, irgendwann)
Aber spater war die Implementation von PosEx eigentlich fast identisch mit Pos... nur noch weitere Parameter, dessen Bereichsprüfung und dann ein anderer einstieg in die Suchschleife (loop). Also Eigentlich sollte das PosEx einen "Hauch" von wenigen CPU-Zyklen langsamer sein. Dann hatte man das FastCode-Projekt teilweise in Delphi integriert und k.A. wie es dann war. Und jetzt klingt es so, als wenn man Pos durch PosEx ersetzt hat, was ja im Prinzip auch praktisch keinen Unterschied macht, wenn beides "gleich" implementiert war. |
AW: PosEx? Oder doch lieber Pos? - Performance!
Ich liebe es wie sich hier bei dieser Routine auf einmal alle so viel Mühe geben die Groß/Kleinschreibung zu beachten :mrgreen:
|
AW: PosEx? Oder doch lieber Pos? - Performance!
Zitat:
Gruß K-H P.S. Laut den Sourcen ist das PosEx in D7 aus dem FastCode-Projekt. |
AW: PosEx? Oder doch lieber Pos? - Performance!
Zitat:
|
AW: PosEx? Oder doch lieber Pos? - Performance!
Wobei Google inzwischen gelernt hat und Minderheiten entsprechend verlinkt.
![]() Kann aber auch daran liegen, daß Google inzwischen die "bösen" erotischen Webseiten weiter unten einsortiert. :stupid: |
AW: PosEx? Oder doch lieber Pos? - Performance!
Wow, selbst die Bilder- und Videosuche ist entsprechend ... harmlos.
|
AW: PosEx? Oder doch lieber Pos? - Performance!
..........nvm
|
AW: PosEx? Oder doch lieber Pos? - Performance!
Liste der Anhänge anzeigen (Anzahl: 3)
Also ich bin kein ASM-Experte aber hab mir das ganze mal im Debugger angeschaut.
Bilder sind im Anhang. Bei dem Bild "pos" sieht man den kompletten ASM-Code der pos-funktion :stupid: Die Stringsuche beginnt bei Adresse 00402FE8 "REPNE SCAN BYTE PTR..." Der ASM-Befehl sucht quasi solange nach einem String bis ECX 0 ist. Bei Bild "posex_main" fällt erstmal auf dass die Funktion anders anfängt. Von der Stringsuchschleife von pos() sieht man erstmal nichts. Aber: z.B. gibt es bei PosEx() ja den 3. Parameter "Offset" der default auf 1 gesetzt ist. Das sieht man auf dem Bild schön bei Adresse 00407CB1 "CMP ECX,1" und "JNZ SHRT findPosi.00407CC1". Wenn man das Offset unberührt lässt (also bei default 1) dann wird der jump JNZ - "jump if not zero" auch nicht genommen und wir landen bei Adresse 00407CBA "CALL findPosi.0040398C". Wenn man dem folgt landet man bei Bild "posex2" und jetzt erkennt man, dass wir dort dann wieder bei der Funktion pos() sind. Also tl;dr: posEx() hat einen jump, ein CMP und ein JNZ mehr als pos() und ist somit langsamer :stupid:. posEx() kann allerdings schneller sein, wenn man das Offset setzt. Ach und: Das ganze hab ich aus Delphi 7 :stupid: :stupid: :stupid: Edit:// Sorry ich wollte eigtl. meinen Beitrag oben editieren. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:21 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz