Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   [Optimiert] Explode Prozedur - Reloaded (Ersatz für CodeLib) (https://www.delphipraxis.net/82268-%5Boptimiert%5D-explode-prozedur-reloaded-ersatz-fuer-codelib.html)

stoxx 24. Feb 2008 23:59

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Zitat:

Danke für die Tipps. Ich habe mittlerweile eine Version, die die FastCode-Gewinner mit einbezieht. Bei Trennern der Länge 1 ist die neue Version um ein vielfaches schneller.
Das habe ich nun ausgiebig getestet und kann man soooo pauschal nicht sagen.
Deine ASM FastPosEx ist in meinem Anwendungsfall überhaupt nicht zu gebrauchen und braucht mehr als doppelt so lange, wie Deine effiziente Pointerlösung. (allerdings ist eine Modifikation notwendig)
Es kommt immer auf den Kontext der Anwendung an, und man sollte es einfach mal austesten.

Im groben kann man aber folgende Ergebnisse zusammenfassen.

1. Die StringDivider im ersten Posting sollte man einsetzen, wenn man die Ergebnisse sowieso in einer TStrings Variable braucht.
2. Man sollte sich überlegen, ob man das nicht irgendwie umgehen kann, in dem man die Elemente in einem dynamischen Array speichert.
(natürlich setlength nicht bei jeder einzelnen erhöhung vergrößern, sondern schrittweise.
3. in der Version im ersten Posting muss noch die lokale Procedure unbedingt entfernt werden. (siehe mein Beitrag)
4. Bei wichtigen zeitkritischen Anwendungen die Explode Funktion aus der Klasse einfach in die eigene Klasse integrieren, die dann direkt mit den Member Variabeln arbeitet ... die Übergabe in TStrings ist sehr lahm....

FastPosEx sollte man nehmen, wenn man einen großen Datenbestand nach selten vorkommenden Strings durchsucht, dann aber wird die Geschwindigkeit unschlagbar gegenüber den anderen Lösungen. Die häufigen Funktionsaufrufe und Übergaben erweisen sich dann als negativ, wenn man nur einen Char als Sperator mit kurzen Zeilen hat. (Bei kurzen Zeilen meinte ich Bildschirmbreite) .. Im Falle meiner 100 MB CSV Referenz-Datei mit ca 90 Zeichen Breite und ca 25 Spalten (wo auch einige Leerspalten enthalten sind .. also einige Kommas nebeneinander) war die Pointerlösung aus dem ersten Posting unschlagbar.

Eine Lösung mit FastPosEx wird umso interessanter, je größer das Verhältnis Wortlänge/Vorkommen des Seperators ist.
Dafür wird dann aber FastPosEx wahnsinnig schnell, im Vergleich zu den anderen Varianten.
Bei einer durchschnittlichen Wortlänge von 5 Zeichen zwischen den Seperatoren ist FastPosEx die Hälfte langsamer.
Ab einer Wortlänge von durchschnittlich 10 Zeichen, ist es ungefähr gleich schnell.
Wobei man die Ergebnisse nicht direkt vergleichen kann, ich bin davon ausgeganen, dass man die Strings eventuell nicht in einer Stringlist braucht ..
Für CSV Dateien erwies es sich als ungeeignet. (zum vergleich: Pointerlösung- 100MB CSV Datei 1500 ms ... dieselbe Funktionalität mit FastPosEx 3500 ms)

alzaimar 25. Feb 2008 08:24

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Ich habe mal die FastCode-Routinen eingebaut.
Ergebnis: Bei einem einstelligen Trennzeichen (z.B. ';') ergeben sich Performancesteigerungen (MB/s) von 10-150% (die 150% natürlich bei extrem langen Strings), bei einem Trennzeichen mit weniger als 4 Zeichen ergeben sich Steigerungen von 10-30%. Bei Trennzeichen mit mehr als 4 Zeichen ist QuickSearch eh am schnellsten, also wird sich da nix tun.

Ich mag TStrings bzw. den Umgang damit.Man hat einen 50% Overhead ggü einem DynArray (dynamische Anpassung des Arrays, jeweils verdoppelung der Größe), dafür muss man sich aber um nix kümmern. Ich finde, mit den 50% kann man in den meisten Fällen leben (Man spart z.B. bei 1.000.000 Lese- und Schreibzugriffen ca. 250ms ein... Na ja.)

Wenn man aber an dem Teil feilen will, dann sollte man ein dynamisches StringArray befüllen.

Eventuell bring es was die TStringDivider-Klasse so umschreiben, das beim Explode gar keine Stringlisten erzeugt werden, sondern nur die Positionen der einzelnen Substrings im Text. Über eine Array-Eigenschaft 'Substrings[Index : Integer]' kann man dann auf die einzelnen Elemente zugreifen. Da hier nur ein String-Copy zum Einsatz kommt (beim Abrufen des SubStrings), könnte das etwas schneller werden.

Weiterhin sollte man die FastMove-Routine einbauen, das dürfte das 'String Copy' nochmals optimieren.

Wenn man dann noch die '"' - Behandlung implementiert, sollte Alle zufrieden sein. Ich mach mich heute Abend mal ans Werk.

mimi 25. Feb 2008 10:31

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Zitat:

Für CSV Dateien erwies es sich als ungeeignet. (zum vergleich: Pointerlösung- 100MB CSV Datei 1500 ms ... dieselbe Funktionalität mit FastPosEx 3500 ms)
Und ich dachte immer ASM sei so schnell..... aber nicht schlecht 100MB mit nur 1500 MS zu durchsuchen, Komplett ? also von vorne bis hinten ?
Zitat:

Wenn man dann noch die '"' - Behandlung implementiert, sollte Alle zufrieden sein.
Ja ! Das währe toll. Dann könnte ich die Funktion in meinem Aktuellen Projekt benutzten. Wenn die so schnell ist. Meins ist leider nicht so schnell.

stoxx 25. Feb 2008 14:08

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Delphi-Quellcode:
Bei einem einstelligen Trennzeichen (z.B. ';') ergeben sich Performancesteigerungen (MB/s) von 10-150% (die 150% natürlich bei extrem langen Strings),

100 chars per line: 1000000 lines in 2907 tics, 343997 lines per sec, 33,6 mb/s (del = ";")

das kann man mal als Referenz für den meinen Rechner nehmen.
Es stimmt, mit Fastcode erreicht man steigerungen in dem Bereich um ungefähr 100 Prozent.
Ich bin aber nun schon bei ca. um die 80 - 90 MB/s,
Wenn man nicht alle Spalten der CSV Datei benötigt, sogar auf 115 MB.
Das langsame sind nämlich die Stringkopien.
Ich habe es mit einem Pointerarray gelöst,das gespeichert wird, und erst beim Get_Zugriff auf den Index, wird der String mit SetString() kopiert.

Zitat:

Wenn man aber an dem Teil feilen will, dann sollte man ein dynamisches StringArray befüllen.
am besten gar nix befüllen :-) nur wenn es gebraucht wird, da würdest Du ja nochmal einen String kopieren, das ist ja das lahme, eine reine PChar verwendung wäre die Lösung. die Fastcode Lösungen haben alle generell den Nachteil, dass sie nur reine Strings annehmen ....
Vielleicht bastel ich mir auch nochmal einen reinen PChar Textreader, dann gänge es sogar noch schneller :-)
Dann entfällt NOCH einmal umkopieren. (100 Prozent Performance mehr)

Zitat:

Eventuell bring es was die TStringDivider-Klasse so umschreiben, das beim Explode gar keine Stringlisten erzeugt werden, sondern nur die Positionen der einzelnen Substrings im Text
so hab ichs gemacht ...

Zitat:

aber nicht schlecht 100MB mit nur 1500 MS zu durchsuchen, Komplett ? also von vorne bis hinten ?
ja, sollte kein Problem sein, die meisten nehmen nur keinen Lesepuffer zum lesen.
(Faktor 10 - 20 langsamer)

schau mal hier, die Rohdaten zu lesen, hast Du ungefähr in 750 ms gemacht ( 100 MB)

http://delphi.pjh2.de/articles/files/files.php


Zitat:

Und ich dachte immer ASM sei so schnell.....
du hast den falschen Schluss gezogen ....
ASM ist genauso schnell wie Delphi. wenn es gut compiliert.
Die Fastcode Lösungen sind oft trickreiche Sachen, man arbeitet mit ASM aber noch mit anderen Ideen.
Sprungadressen auf Funktionen anhand der Übergabeparameter berechnen usw.
Musst Du dir mal ansehen, reines Assember ist auch nicht schneller.

Das langsame sind die Strings ... einmal Setstring aus dem String heraus in einen Tempbuffer, .. und dann noch einmal!! in TStrings hinein.

schau Dir mal die procedure TStrings.SetTextStr(const Value: string); in SysUtils an ...

die fast function StrPosJOH wäre wahrscheinlich noch interessant, um die Position zu finden. dürfte Schneller sein, als die Schleife:

http://coding.derkeiler.com/Archive/.../msg00102.html

und dann in Assembler, aber da ist wohl ein Uppercase drin ....

http://coding.derkeiler.com/Archive/.../msg00057.html

hab ich aber noch nicht eingebaut

alzaimar 25. Feb 2008 14:37

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Die JOH_Pos-funktionen sind bei Delimitern <= 4 Zeichen schneller als das Quicksearch, bei einem Zeichen ist die JOH-charPos Funktion noch schneller. Viel schneller.

Und ich denke, die TStringDivider-Version mit 'copy-string-on-demand' sollte dann auch dem strengsten Kritiker gefallen. Hast schon Recht...

stoxx 25. Feb 2008 14:43

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Liste der Anhänge anzeigen (Anzahl: 1)
also mit der Lösung im Anhang bin ich auf 93,1 MB pro Sekunden.
Im Vergleich zur ersten Lösung eine Steigerung um 300 Prozent.


Using TStringExploder in TStringList
100 chars per line; Itemlänge: 10; 1000000 lines in 1047 tics, 955110 lines per sec, 93,3 mb/s (del = ";")
10000 chars per line; Itemlänge: 100; 50000 lines in 1844 tics, 27115 lines per sec, 264,8 mb/s (del = ";")
1000000 chars per line; Itemlänge: 1000; 500 lines in 1610 tics, 311 lines per sec, 303,3 mb/s (del = ";")
100 chars per line; Itemlänge: 5; 1000000 lines in 1422 tics, 703235 lines per sec, 68,7 mb/s (del = ";")
1000 chars per line; Itemlänge: 5; 500000 lines in 6796 tics, 73573 lines per sec, 71,8 mb/s (del = ";")




Noch schneller wird es, wenn man nur die Hälfte der Columns benötigt !!

zum Testen.

For ColIDX := 0 To (d.ColCount Div 2) Do begin
// s.Add(d.Columns[ColIDX]); // Bremse ....
s1 := d.Columns[ColIDX];

end;


aber bitte vorsichtig, die kapslung stürzt noch ab bei sehr großen Strings, wahscheinlich wegen dem Arry, ist alles ungetestet. hatte keine Zeit mehr.
am besten die Funktionalitäts-logik irgendwie in die eigene Klasse die es benötigt, integrieren ...
unterstützt auch im Moment nur die Suche nach einem Zeichen ...

stoxx 25. Feb 2008 14:45

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Zitat:

Die JOH_Pos-funktionen sind bei Delimitern <= 4 Zeichen schneller als das Quicksearch
vielleicht bringt ja die JOH Pos auf PChar basierend noch mehr Performance ;-)
http://fastcode.sourceforge.net/Fast...trLenBV132.zip

Zitat:

Und ich dachte immer ASM sei so schnell.....
und hier sieht man mal, dass die Suche nach einem Zeichen (Null) von JOH in Pascal wesentlich schneller sein können, als eine ASM Routine .... :-)


http://fastcode.sourceforge.net/Fast...nchmark132.xls

stoxx 25. Feb 2008 15:27

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
hmmm .. weiß jemand was der da tut??

Könnte man die Operationen auch so gestalten, dass es auch mit einem beliebigen Zeichen funktioniert?
Oder ist diese Arithmetik nur für Null einsetzbar?


Delphi-Quellcode:
function StrLen_JOH_PAS_3_a(const Str: PChar): Cardinal;
var
  P, PStr: PChar;
  I, J: Integer;
begin
  if Str^ = #0 then
    begin
      Result := 0; Exit;
    end;
  if Str[1] = #0 then
    begin
      Result := 1; Exit;
    end;
  if Str[2] = #0 then
    begin
      Result := 2; Exit;
    end;
  if Str[3] = #0 then
    begin
      Result := 3; Exit;
    end;
 P := Pointer(Str);
 PStr := P;
 P := Pointer(Integer(P) and -4);
 repeat
   Inc(P, 4);
   I := PInteger(P)^;
   J := I - $01010101;
   I := not(I);
   I := I and J;
 until (I and $80808080) <> 0;
 Result := P - PStr;
 if I and $80 = 0 then
   if I and $8000 <> 0 then
     Inc(Result)
   else
     if I and $800000 <> 0 then
       Inc(Result, 2)
     else
       Inc(Result, 3)
end;
ist vom Benchmark doppelt so schnell, wie eine einfache schleife und jedes Byte anzusehen ..

Delphi-Quellcode:
function StrLen_JOH_PAS_1_a(const Str: PChar): Cardinal;
var
  P : PChar;
begin
  P := Str;
  while P^ <> #0 do
    Inc(P);
  Result := P - Str;
end;

alzaimar 25. Feb 2008 16:18

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Zitat:

Zitat von stoxx
also mit der Lösung im Anhang bin ich auf 93,1 MB pro Sekunden.

Aber du liest die Strings nicht aus, oder? Du rufst doch nur 'explode' auf, gell? :mrgreen: :zwinker:

alzaimar 25. Feb 2008 16:21

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Zitat:

Zitat von stoxx
also mit der Lösung im Anhang bin ich auf 93,1 MB pro Sekunden.

Aber du liest die Strings nicht aus, oder? Du rufst doch nur 'explode' auf, gell? :mrgreen: :zwinker:

stoxx 25. Feb 2008 16:25

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Zitat:

Zitat von alzaimar
Zitat:

Zitat von stoxx
also mit der Lösung im Anhang bin ich auf 93,1 MB pro Sekunden.

Aber du liest die Strings nicht aus, oder? Du rufst doch nur 'explode' auf, gell? :mrgreen: :zwinker:

doch, doch, die werden schon ausgelesen, nämlich einem String zugewiesen.
Soviel bräuchte man, wenn man daraus irgendwas machen will (Zahlen umwandeln oder sonstwas)

Das wäre ein einziger Zugriff auf den Original String, da ich diesen mir auch nicht als Member Variable speicher.
(Copy on Write) sobald man da irgendwas verändert.

für ein oder zwei Zeichen hätte ich noch eine Idee für Dich, wenn Du wirklich unbedingt alles in TStrings haben willst.

Du nimmst einfach den Original String, setzt einen Pointer drauf, und ersetzt das Trennzeichen durch eine #10
oder#13.

Dann wirfst Du den gesamten String mit einem Rutsch mit TStrings.text drauf.
Danach machst Du Deine Änderungen wieder rückgängig, und ersetzt Deine selber gesetzten #10 wieder :-)
Oder wenn es auch mit einem Substring länger als 2 Zeichen funktionieren soll, kööönte man sich ja auch mal in der Unit Classes die
Methode: procedure TStrings.SetTextStr(const Value: string); ansehen und ein wenig umstrukturieren.


So hättest Du es auch in TStrings, und wahrscheinlich genauso schnell :)

Zitat:

Ich finde, mit den 50% kann man in den meisten Fällen leben (Man spart z.B. bei 1.000.000 Lese- und Schreibzugriffen ca. 250ms ein... Na ja.)
ja, wenn es einmal da ist, aber um mit Strings zu operieren, um sie weiter zu verarbeiten , naaaaja :-)
Da bracht es wesentlich länger, da TStrings ja mit SetString sich eine Kopie vom OriginalString holt ...

stoxx 25. Feb 2008 16:26

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
ups, dopptelt (gelöscht)

stoxx 25. Feb 2008 16:38

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Zitat:

Zitat von alzaimar
Zitat:

Zitat von stoxx
also mit der Lösung im Anhang bin ich auf 93,1 MB pro Sekunden.

Aber du liest die Strings nicht aus, oder? Du rufst doch nur 'explode' auf, gell? :mrgreen: :zwinker:

das ist MIT auslesen, ohne auslesen und nur explode kommt man auf 215 MB/s :mrgreen:
Und wenn man nur einen string braucht vielleicht nur auf 210 MB/s? .. hihi .. keine Ahung.
kann man testen ...


ohne auslesen, nur explode:

Using TStringExploder in TStringList
100 chars per line; Itemlänge: 10; 1000000 lines in 453 tics, 2207506 lines per sec, 215,6 mb/s (del = ";")
10000 chars per line; Itemlänge: 100; 50000 lines in 1375 tics, 36364 lines per sec, 355,1 mb/s (del = ";")
1000000 chars per line; Itemlänge: 1000; 500 lines in 1344 tics, 372 lines per sec, 363,3 mb/s (del = ";")
100 chars per line; Itemlänge: 5; 1000000 lines in 422 tics, 2369668 lines per sec, 231,4 mb/s (del = ";")
1000 chars per line; Itemlänge: 5; 500000 lines in 1937 tics, 258131 lines per sec, 252,1 mb/s (del = ";")

alzaimar 25. Feb 2008 16:38

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Zitat:

Zitat von stoxx
Zitat:

Zitat von alzaimar
Zitat:

Zitat von stoxx
also mit der Lösung im Anhang bin ich auf 93,1 MB pro Sekunden.

Aber du liest die Strings nicht aus, oder? Du rufst doch nur 'explode' auf, gell? :mrgreen: :zwinker:

doch, doch, die werden schon ausgelesen, nämlich einem String zugewiesen.

:shock: Goil

stoxx 1. Mär 2008 18:18

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Unten genannte Tests sowie Zeitmessung eingearbeitet: Es ist ein komplettes Projekt mit Funktions- und Speed-Test. Bitte versucht, Teile davon zu optimieren (ASM, Pointer arithmetic etc.).
isch hab noch bissi dran rumgeschraubt *g*
zumindest für einen Seperator mit der Zeichenlänge eins :-)
bist Du noch schneller mit asm + strings, als mit einer optimierten Pointerlösung ? .. würde mich jetzt mal interessieren


Hier der Vergleich auf einem "alten" 3200+ AMD als Referenz ...

-------------------------------------------------
Compiliertes Eingangsbeispiel von alzaimar
-------------------------------------------------
100 chars per line: 1000000 lines in 6469 tics, 154583 lines per sec, 15,1 mb/s (del = ";")
10000 chars per line: 50000 lines in 9594 tics, 5212 lines per sec, 50,9 mb/s (del = ";")
1000000 chars per line: 500 lines in 3953 tics, 126 lines per sec, 123,5 mb/s (del = ";")


------------------------------------------------
mit Delphi 2007 compiliert ( Codegear hat ein paar Lösungen vom Fastcode Projekt intern integriert)
-------------------------------------------------
Using TStringDivider in TStringList
100 chars per line: 1000000 lines in 3844 tics, 260146 lines per sec, 25,4 mb/s (del = ";")
10000 chars per line: 50000 lines in 4375 tics, 11429 lines per sec, 111,6 mb/s (del = ";")
1000000 chars per line: 500 lines in 3641 tics, 137 lines per sec, 134,1 mb/s (del = ";")


-------------------------------------------------
TFastStringExploder .....
-------------------------------------------------
Using TStringExploder in TStringList
100 chars per line; Itemlänge: 10; 1000000 lines in 937 tics, 1067236 lines per sec, 104,2 mb/s (del = ";")
10000 chars per line; Itemlänge: 100; 50000 lines in 1234 tics, 40519 lines per sec, 395,7 mb/s (del = ";")
1000000 chars per line; Itemlänge: 1000; 500 lines in 968 tics, 517 lines per sec, 504,4 mb/s (del = ";")

toms 2. Mär 2008 06:18

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
TFastStringExploder ist leider nicht D6/D7/.. kompatibel, da private Felder im Record verwendet werden.

Musst für einen Test unter D6
Delphi-Quellcode:
TFastStringExploder = Class
ändern und das static entfernen.
Nachtrag: War keine gute Idee, gib dann eine AV.

alzaimar 2. Mär 2008 08:27

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Liste der Anhänge anzeigen (Anzahl: 1)
Du must nur einen Konstruktor/Destruktor einbauen, der die Felder initialisiert. Weiterhin ist da ein Bug beim Vergrößern des FPointer-Arrays...

Hier eine Version, die bei mir funktioniert.

stoxx 2. Mär 2008 13:50

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Zitat:

Zitat von alzaimar
Hier eine Version, die bei mir funktioniert.

ja, da war ein Bug im Array vergrößern drin, die version die Du hochgeladen hast, war nicht die letzte und schnellste :-)
Ist auch noch ein kleiner Bug drin ( in der letzten) .. muss ich aber nochmal drüber nachdenken.
ich ersetzte ja die Null nach einem String mit dem FSeperator .. die müsste man wieder herstellen.
Delphi selber geht in seinen TSTrings Routinen auch davon aus, dass die Null garantiert da ist, nach einem String, ich denke, man kann sich darauf also auch verlassen.
Oder man würde nur das letzte Zeichen des Strings ersetzen, und wieder herstellen ...

stoxx 2. Mär 2008 14:14

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Zitat:

Zitat von toms
Nachtrag: War keine gute Idee, gib dann eine AV.

die gab es nur, weil Du wahrscheinlich mit einem Resourcestring getestet hast :-)
das geht nicht so wirklich ....
nur normale Strings ...

also NICHT:

Delphi-Quellcode:
var s : String;
begin
    s := 'ghh,dddd';
    Exploder.explode(s);

end;

sondern:

Delphi-Quellcode:
var s : String;
begin
   
    s := 'ghh,dddd,';
    s := s + 'AAA';
    Exploder.explode(s);

end;
bei einer Klasse oder umstellen des Codes müsste man aber erst wieder noch die Sprungadresse auf Startloop optimieren ... ( bringt ungefähr 10-20 Prozent bei mir) .. je nachdem wie schlecht sie ist

C.Schoch 2. Mär 2008 16:05

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi,
Ich hab eine kleine Erweiterung von alzaimars Version die mit einem Dynamischen Array arbeitet das bringt durch den verringerten Verwaltungsaufwand noch mal 5 - 50% Geschwindigkeit
Vielleicht kann diese Ergänzung gleich in zukünftige Versionen mit einfließen :wink:

moonwhaler 14. Apr 2008 13:16

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Erstmal ein dickes Dankeschön! Dieses Teil ist absolut genial! Eine Frage / Bitte habe ich aber noch: Ich muss häufig mit Unicode-Strings (WideString) arbeiten, leider funktioniert die aktuelle Version aber damit nicht. Das mag natürlich auch daran liegen, dass man die Ansi-String Version von TStringList verwendet (ich selbst hab mein komplettes Programm mittlerweile auf WideString und TTntStringList umgebaut).

Ein erster Versuch den Code in Richtung WideString zu portieren hat zwar (augenscheinlich) geklappt, jedoch ist er mit bösen Exceptions rausgeflogen (PWideChar, statt PChar usw.). Ist es möglich mir bei einer solchen Implementierung zu helfen, oder gibt es gar bereits eine solche?

Vielen Dank!
Christian

SubData 9. Sep 2008 13:44

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Wenn der Divider mit einem leeren String aufgerufen wird, gibt es eine Zugriffsverletzung.

himitsu 1. Dez 2009 16:41

Re: [Optimiert] Explode Prozedur - Reloaded (Ersatz für Code
 
Liste der Anhänge anzeigen (Anzahl: 1)
hab mal ein paar Probleme bezüglich Unicode versucht zu beheben
ist allerdings noch nicht getestet
(und 'nen Codeformatter ist mal drübergerauscht ... dort drinnen mischten sich vorher mehrer Styles)

Grund: http://www.delphipraxis.net/internal...106505#1106505

als Quelle wurde die Unit aus Beitrag #1 genommen

Zitat:

Zitat von himitsu
PChar nach Länge für Copy wurde nicht halbiert ... siehe deine Ergebnisse
Länge für CompareMem wurde nicht verdoppelt, welches in falschen Vergleichen enden könnte.


Z4ppy 15. Aug 2010 12:44

AW: [Optimiert] Explode Prozedur - Reloaded (Ersatz für CodeLib)
 
Delphi 7 meldet mir:
Zitat:

[Warning] csExplode.pas(397): Return value of function 'TMultiCharPatternStringDivideIterator.MoveNext' might be undefined
MfG Z4ppy

alzaimar 16. Aug 2010 07:53

AW: [Optimiert] Explode Prozedur - Reloaded (Ersatz für CodeLib)
 
Ja. Und? Woran könnte das liegen?

Z4ppy 16. Aug 2010 15:44

AW: [Optimiert] Explode Prozedur - Reloaded (Ersatz für CodeLib)
 
Vielleicht daran, dass der Rückgabewert nicht sofort initialisiert wird sondern erst im if :stupid:
Aber da ich nicht weiss, was diese Funktion macht (ich habs aber auch nicht versucht herauszufinden), habe ich da nicht daran rumgefummelt...

MfG Z4ppy

DeddyH 16. Aug 2010 16:01

AW: [Optimiert] Explode Prozedur - Reloaded (Ersatz für CodeLib)
 
Ich habe die Funktion jetzt nicht in ihrer ganzen Logik erfasst, aber man müsste sie so umschreiben können:
Zitat:

Delphi-Quellcode:
      If fEndOfText Then
        Result := False
      Else
        begin
          ...
        end;

wird zu:
Delphi-Quellcode:
Result := False;
      If not fEndOfText Then
        begin
          ...
        end;

Christian Seehase 16. Aug 2010 20:23

AW: [Optimiert] Explode Prozedur - Reloaded (Ersatz für CodeLib)
 
Moin Detlef,

IMHO sollte man Result erst möglichst spät verwenden, da man ansonsten das (E)AX-Register früh blockiert. Also Folge wäre der resultierende Code dann nicht so gut optimierbar.
Je nach Anwendungsfall kann sich das auf die Performance auswirken.

himitsu 16. Aug 2010 20:54

AW: [Optimiert] Explode Prozedur - Reloaded (Ersatz für CodeLib)
 
Delphi lagert Result (falls es wirklich in EAX oder EAX+EDX zurückgegeben wird) notfalls auf ein anderes Register oder den Stack aus ... blockiert wird also nichts. :-D

[ot] aber schön dich mal wieder aktiver zu sehn :)

Z4ppy 16. Aug 2010 21:05

AW: [Optimiert] Explode Prozedur - Reloaded (Ersatz für CodeLib)
 
DeddyH:
Vielleicht aber auch:
Delphi-Quellcode:
      If fEndOfText Then
        Result := False
      Else
        begin
Result:=True;
          ...
        end;
Auf Zeile 332 ist übrigens eine Funktion einer anderen Kompo mit gleichem Namen so geschrieben.

MfG Z4ppy

Christian Seehase 17. Aug 2010 19:35

AW: [Optimiert] Explode Prozedur - Reloaded (Ersatz für CodeLib)
 
Zitat:

Zitat von himitsu (Beitrag 1042626)
Delphi lagert Result (falls es wirklich in EAX oder EAX+EDX zurückgegeben wird) notfalls auf ein anderes Register oder den Stack aus ... blockiert wird also nichts. :-D

Sicher, wird dann, nach Möglichkeit, auf andere Speicherorte ausgewichen, aber da EAX öfter benötigt wird, kann das den resultierenden Objectcode negativ beeinflussen. ;-)

himitsu 17. Aug 2010 19:46

AW: [Optimiert] Explode Prozedur - Reloaded (Ersatz für CodeLib)
 
Delphi lagert es nur einmal aus und es wird dann vorm RET auf EAX kopiert.
Result wird in soeinem Fall einfach wie eine lokale Variable behandelt und erst zum Schluß als "Result" gesetzt.

Es sollte also nicht unbedingt extreme Einbusen geben.

Code:
function Test: Integer;
begin
  Result := 123;
  asm mov eax, 789; end;
end;

mov edx,$0000007b // Result := 123;
mov eax,$00000315  // asm mov eax, 789; end;
mov eax,edx       // end;
ret


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:30 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz