Delphi-PRAXiS
Seite 11 von 16   « Erste     91011 1213     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Anzahl eines Zeichens im String ermitteln (https://www.delphipraxis.net/116372-anzahl-eines-zeichens-im-string-ermitteln.html)

EgonHugeist 14. Jul 2018 06:15

AW: Anzahl eines Zeichens im String ermitteln
 
Liste der Anhänge anzeigen (Anzahl: 1)
Danke für für den letzten Stand.

Ich denke du hast recht. Simples Ausschlusverfahren:

Ich habe mal mein XE10.2-W32 Compilate (release) angehängt. Wenn deine Version immernoch die schnellste mit der EXE ist, dann ist der Compiler ausgeschlossen und da macht deine Hardware einen guten Job.

Bei mir sehen die Ergebnisse (minimale Schwankungen im >5% ) ziehmlich gleich aus.
YFI:
Zitat:

Calibrate - Target missed: 0 <> 7982
00000 Calibrate
04817 1234588 miep
08310 Ydobon
04108 marabu
05045 Missionar
04449 alzaimar
04252 Uwe Raabe StringCountChar
04068 Uwe Raabe StringCountCharFor
04027 KodeZwerg CountCharInString
10237 KodeZwerg CharInStringA
04517 Neutral General CharCountAsm
04350 Uwe Raabe CharCount
03988 Egon Hugeist CharCount_1
04494 Egon Hugeist CharCount_2
04544 Egon Hugeist CharCount_Double_Sided_3
03775 Egon Hugeist CharCount_Double_Sided_4
04657 Delphi CountChar
Aber ist schon interessant, welche Lösungswege existieren! Der Einzeiler über den RecordHelper hat was, ist jedoch nicht Portabel(eg. alte Compiler oder FPC). Der Einzeiler von Ydobon ist extrem kreativ.
Ich persönlich tendiere immer dazu ein set von function zu sammeln und diese Wiederzubenutzen..

EgonHugeist 14. Jul 2018 09:56

AW: Anzahl eines Zeichens im String ermitteln
 
Liste der Anhänge anzeigen (Anzahl: 1)
Double Post. Hab sind noch zwei:

mit direktem Inc des Boolschen ordinals:
Delphi-Quellcode:
function EH_CharCount_5(const S: string; C: Char): Cardinal;
var
  P, PEnd: PChar;
begin
  Result := 0;
  P := Pointer(S);
  if P = nil then Exit;
  PEnd := P + PStrLenInt(NativeUInt(P) - SizeOf(StrLenInt))^-8;
  while P < PEnd do begin
    //comapre 8 Chars per loop
    //this is a simple technic to reduce the loop.
    Inc(Result, Ord(P^=C));
    Inc(Result, Ord((P+1)^=C));
    Inc(Result, Ord((P+2)^=C));
    Inc(Result, Ord((P+3)^=C));
    Inc(Result, Ord((P+4)^=C));
    Inc(Result, Ord((P+5)^=C));
    Inc(Result, Ord((P+6)^=C));
    Inc(Result, Ord((P+7)^=C));
    Inc(P, 8);
  end;
  Inc(PEnd, 8);
  while P < PEnd do begin
    Inc(Result, Ord(P^=C));
    Inc(P);
  end;
end;
ohne direktem Inc des Boolschen ordinals mit if ? then
Delphi-Quellcode:
function EH_CharCount_6(const S: string; C: Char): Cardinal;
var
  P, PEnd: PChar;
begin
  Result := 0;
  P := Pointer(S);
  if P = nil then Exit;
  PEnd := P + PStrLenInt(NativeUInt(P) - SizeOf(StrLenInt))^-8;
  while P < PEnd do begin
    //comapre 8 Chars per loop
    //this is a simple technic to reduce the loop.
    if P^    = C then Inc(Result);
    if (P+1)^ = C then Inc(Result);
    if (P+2)^ = C then Inc(Result);
    if (P+3)^ = C then Inc(Result);
    if (P+4)^ = C then Inc(Result);
    if (P+5)^ = C then Inc(Result);
    if (P+6)^ = C then Inc(Result);
    if (P+7)^ = C then Inc(Result);
    Inc(P, 8);
  end;
  Inc(PEnd, 8);
  while P < PEnd do begin
    if P^=C then
      Inc(Result);
    Inc(P);
  end;
end;
Dies ist die eine typische Technik um die Loops zu reduzieren. Man kann das noch weiter aufbohren für seeehhhr lange strings.
Bei mir rockt EH_CharCount_5 am schnellsten:
Zitat:

00000 Calibrate
04814 1234588 miep
08272 Ydobon
04056 marabu
05014 Missionar
04429 alzaimar
04238 Uwe Raabe StringCountChar
04067 Uwe Raabe StringCountCharFor
04029 KodeZwerg CountCharInString
10193 KodeZwerg CharInStringA
04606 Neutral General CharCountAsm
04501 Uwe Raabe CharCount
04016 Egon Hugeist CharCount_1
04490 Egon Hugeist CharCount_2
04541 Egon Hugeist CharCount_Double_Sided_3
03771 Egon Hugeist CharCount_Double_Sided_4
03199 Egon Hugeist CharCount_5
03803 Egon Hugeist CharCount_6
04657 Delphi CountChar
Compilat hängt an zum Vergleich.

Uwe Raabe 14. Jul 2018 10:04

AW: Anzahl eines Zeichens im String ermitteln
 
Zitat:

Zitat von EgonHugeist (Beitrag 1407253)
Ich habe mal mein XE10.2-W32 Compilate (release) angehängt. Wenn deine Version immernoch die schnellste mit der EXE ist, dann ist der Compiler ausgeschlossen und da macht deine Hardware einen guten Job.

Da scheint es beim Compiler doch noch Unterschiede zu geben, aber auch der Prozessor spielt wohl eine Rolle:

Zitat:

00000 Calibrate
03609 1234588 miep
05863 Ydobon
02910 marabu
03662 Missionar
03607 alzaimar
03121 Uwe Raabe StringCountChar
03025 Uwe Raabe StringCountCharFor
02665 KodeZwerg CountCharInString
11464 KodeZwerg CharInStringA
05983 Neutral General CharCountAsm
03961 Uwe Raabe CharCount
04070 Egon Hugeist CharCount_1
03793 Egon Hugeist CharCount_2
03114 Egon Hugeist CharCount_Double_Sided_3
03126 Egon Hugeist CharCount_Double_Sided_4
03805 Delphi CountChar

Zitat:

Zitat von EgonHugeist (Beitrag 1407257)
Dies ist die eine typische Technik um die Loops zu reduzieren.

... und ein direkter Weg ins Desaster, wenn die Stringlänge nicht durch 8 teilbar ist! Die Bedingung der ersten While-Schleife passt nicht so richtig, oder?

EgonHugeist 14. Jul 2018 10:10

AW: Anzahl eines Zeichens im String ermitteln
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1407258)
Zitat:

Zitat von EgonHugeist (Beitrag 1407253)
Ich habe mal mein XE10.2-W32 Compilate (release) angehängt. Wenn deine Version immernoch die schnellste mit der EXE ist, dann ist der Compiler ausgeschlossen und da macht deine Hardware einen guten Job.

Da scheint es beim Compiler doch noch Unterschiede zu geben, aber auch der Prozessor spielt wohl eine Rolle:
....

Puff, damit hab ich jetzt nicht wirklich gerechnet. Bezhalt vs. Free..

Zitat:

Zitat von Uwe Raabe (Beitrag 1407258)
Zitat:

Zitat von EgonHugeist (Beitrag 1407257)
Dies ist die eine typische Technik um die Loops zu reduzieren.

... und ein direkter Weg ins Desaster, wenn die Stringlänge nicht durch 8 teilbar ist! Die Bedingung der ersten While-Schleife passt nicht so richtig, oder?

Desaster? Wie teilbar?? Uwe ich teile nix! Ich nehm dem PEnd gleich im Eingang 8 chars weg (Subtraktion) und behalte mir die für die letzte tiny loop vor.. Somit ist das Ergebnis garantiert, oder sieht das jemand anders? Der Code passt, sind jedoch typos drin die behalten werden dürfen :stupid:

Harry Stahl 14. Jul 2018 10:23

AW: Anzahl eines Zeichens im String ermitteln
 
Also ich finde die ganzen Varianten höchst interessant und man erfährt dabei ein wenig, wo typische bottlenecks sitzen.:thumb:

String.CountChar kannte ich nicht, also insofern wieder was nützliches dazugelernt (hatte dafür nur eine eigene Funktion).

Cool wäre auch, eine Funktion zu haben, welche nicht nur die Anzahl der Vorkommen des Chars ermittelt, sondern auch noch deren Position z.B. in einem Array zurück gibt. Das könnte auch noch an verschiedenen Stellen hilfreich sein.

Eine fertige Funktion scheint es da aber nicht zu geben, oder (String.split habe ich gesehen, gibt aber ein Array der Teilstrings zurück, ich wäre aber erst mal nur an den Positionen des gesuchten Chars interessiert)?

Uwe Raabe 14. Jul 2018 10:27

AW: Anzahl eines Zeichens im String ermitteln
 
Zitat:

Zitat von EgonHugeist (Beitrag 1407259)
Ich nehm dem PEnd gleich im Eingang 8 chars weg und behalte mir die für die letzte tiny loop vor

OK, ich hatte die -8 bei der Berechnung von PEnd übersehen. Sorry!

Die hiesigen Ergebnisse für Win32:
Zitat:

00000 Calibrate
03574 1234588 miep
05938 Ydobon
03004 marabu
03677 Missionar
03600 alzaimar
02959 Uwe Raabe StringCountChar
02968 Uwe Raabe StringCountCharFor
02704 KodeZwerg CountCharInString
07159 KodeZwerg CharInStringA
03950 Neutral General CharCountAsm
02828 Uwe Raabe CharCount
03164 Egon Hugeist CharCount_1
03819 Egon Hugeist CharCount_2
02956 Egon Hugeist CharCount_3
03005 Egon Hugeist CharCount_4
02297 Egon Hugeist CharCount_5
03501 Egon Hugeist CharCount_6
03737 Delphi CountChar
und für Win64:
Zitat:

00000 Calibrate
03678 1234588 miep
07461 Ydobon
03584 marabu
04310 Missionar
03687 alzaimar
08523 Uwe Raabe StringCountChar
03584 Uwe Raabe StringCountCharFor
02865 KodeZwerg CountCharInString
07506 KodeZwerg CharInStringA
Neutral General CharCountAsm - Target missed: 0 <> 7982
00000 Neutral General CharCountAsm
02181 Uwe Raabe CharCount
03025 Egon Hugeist CharCount_1
03776 Egon Hugeist CharCount_2
02747 Egon Hugeist CharCount_3
03028 Egon Hugeist CharCount_4
02964 Egon Hugeist CharCount_5
03358 Egon Hugeist CharCount_6
03829 Delphi CountChar

Harry Stahl 14. Jul 2018 10:40

AW: Anzahl eines Zeichens im String ermitteln
 
Um es selber nachvollziehen zu können: Wie ist denn

PStrLenInt

definiert?

Uwe Raabe 14. Jul 2018 10:40

AW: Anzahl eines Zeichens im String ermitteln
 
Zitat:

Zitat von Harry Stahl (Beitrag 1407261)
Eine fertige Funktion scheint es da aber nicht zu geben, oder (String.split habe ich gesehen, gibt aber ein Array der Teilstrings zurück, ich wäre aber erst mal nur an den Positionen des gesuchten Chars interessiert)?

Nein, sowas gibt es bislang noch nicht.

Uwe Raabe 14. Jul 2018 10:42

AW: Anzahl eines Zeichens im String ermitteln
 
Zitat:

Zitat von Harry Stahl (Beitrag 1407263)
Um es selber nachvollziehen zu können: Wie ist denn

PStrLenInt

definiert?

Steht im Source in einem der Attachments weiter oben.

Delphi-Quellcode:
type
  //zentral deklariert
  PStrLenInt = ^StrLenInt;
  StrLenInt = {$IFDEF FPC}SizeInt{$ELSE}LongInt{$ENDIF};

Harry Stahl 14. Jul 2018 10:49

AW: Anzahl eines Zeichens im String ermitteln
 
OK, Danke Uwe.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:15 Uhr.
Seite 11 von 16   « Erste     91011 1213     Letzte »    

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