AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Anzahl eines Zeichens im String ermitteln
Thema durchsuchen
Ansicht
Themen-Optionen

Anzahl eines Zeichens im String ermitteln

Ein Thema von DevidEspenschied · begonnen am 27. Jun 2008 · letzter Beitrag vom 17. Jul 2018
Antwort Antwort
Seite 13 von 16   « Erste     3111213 1415     Letzte »    
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#121

AW: Anzahl eines Zeichens im String ermitteln

  Alt 15. Jul 2018, 00:01
Hier schau mal selbst, das ist mit nur 50000 Zeichen/Bytes, achte auf den Ydobon Zeitwert. Katastrophal bei mir.
Diese Ergebnisse sind nicht unter optimalen Voraussetzungen entstanden da alle Kerne mit was anderem ausgelastet sind.
Zitat:
KodeZwerg's custom Benchmark - DP CountCharInString Edition

Benchmark: Sleep(500)
501037 Nanoseconds wasted. As closer this is to 500000 more accurate Results are given.

Benchmark: Generate Random Data String (50000 chars) Charset: [aA0-zZ9]
609 Nanoseconds wasted.

Benchmark: 1234588 miep(Data, 'X')
141 Nanoseconds wasted. (found X = 748 times)

Benchmark: Ydobon Length(Data)-Length(StringReplace(Data, 'X', '', [rfReplaceAll]))
21149 Nanoseconds wasted. (found X = 748 times)

Benchmark: marabu Occurs(Data, 'X')
201 Nanoseconds wasted. (found X = 748 times)

Benchmark: Missionar cCount(Data, 'X')
139 Nanoseconds wasted. (found X = 748 times)

Benchmark: alzaimar IFCount(Data, 'X')
122 Nanoseconds wasted. (found X = 748 times)

Benchmark: Uwe Raabe StringCountChar(Data, 'X')
122 Nanoseconds wasted. (found X = 748 times)

Benchmark: KodeZwerg CountCharInString(Data, 'X')
160 Nanoseconds wasted. (found X = 748 times)

Benchmark: KodeZwerg CharInStringA(Data, 'X')
253 Nanoseconds wasted. (found X = 748 times)

Benchmark: Uwe Raabe CharCount(Data, 'X')
89 Nanoseconds wasted. (found X = 748 times)

Benchmark: Uwe Raabe CharCount2(Data, 'X')
58 Nanoseconds wasted. (found X = 748 times)

Benchmark: EgonHugeist CharCount3(Data, 'X')
74 Nanoseconds wasted. (found X = 748 times)

Benchmark: Neutral General CharCountAsm(Data, 'X', Length(Data))
115 Nanoseconds wasted. (found X = 748 times)

Benchmark: EgonHugeist EH_CharCount4(Data, 'X')
76 Nanoseconds wasted. (found X = 748 times)

Benchmark: StrScanFast(Data, 'X')
1 Nanoseconds wasted. (found X = 49895 times)

Benchmark: Generate Random Binary Data String (50000 bytes)
324 Nanoseconds wasted.

Benchmark: 1234588 miep(Data, 'X')
109 Nanoseconds wasted. (found X = 180 times)

Benchmark: Ydobon Length(Data)-Length(StringReplace(Data, 'X', '', [rfReplaceAll]))
5814 Nanoseconds wasted. (found X = 180 times)

Benchmark: marabu Occurs(Data, 'X')
204 Nanoseconds wasted. (found X = 180 times)

Benchmark: Missionar cCount(Data, 'X')
131 Nanoseconds wasted. (found X = 180 times)

Benchmark: alzaimar IFCount(Data, 'X')
108 Nanoseconds wasted. (found X = 180 times)

Benchmark: Uwe Raabe StringCountChar(Data, 'X')
109 Nanoseconds wasted. (found X = 180 times)

Benchmark: KodeZwerg CountCharInString(Data, 'X')
1 Nanoseconds wasted. (found X = 1 times)

Benchmark: KodeZwerg CharInStringA(Data, 'X')
71 Nanoseconds wasted. (found X = 1 times)

Benchmark: Uwe Raabe CharCount(Data, 'X')
1 Nanoseconds wasted. (found X = 1 times)

Benchmark: Uwe Raabe CharCount2(Data, 'X')
63 Nanoseconds wasted. (found X = 180 times)

Benchmark: EgonHugeist CharCount3(Data, 'X')
59 Nanoseconds wasted. (found X = 180 times)

Benchmark: Neutral General CharCountAsm(Data, 'X', Length(Data))
154 Nanoseconds wasted. (found X = 180 times)

Benchmark: EgonHugeist EH_CharCount4(Data, 'X')
67 Nanoseconds wasted. (found X = 180 times)

Benchmark: StrScanFast(Data, 'X')
1 Nanoseconds wasted. (found X = 75 times)
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#122

AW: Anzahl eines Zeichens im String ermitteln

  Alt 15. Jul 2018, 00:50
Delphi 2009 war ja die erste Version mit Unicode. Vermutlich war dort die Umsetzung von StringReplace schlicht noch nicht so gut.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#123

AW: Anzahl eines Zeichens im String ermitteln

  Alt 15. Jul 2018, 02:01
screenshot-15_07.jpgSo in etwa würde neue GUI aussehen.
Wem noch mehr sinnvolle Optionen einfallen, bitte melden.

Edit
Ps: Ein Cancel Button ist nun vorhanden
Gruß vom KodeZwerg

Geändert von KodeZwerg (15. Jul 2018 um 02:06 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#124

AW: Anzahl eines Zeichens im String ermitteln

  Alt 15. Jul 2018, 02:41
Dann möchte ich meine schnell zusammengeschrieben Assembler-Rountine auch noch ins Rennen werfen.
Delphi 2009 verweigert mir Deinen Code. Benötige ich dafür ein aktuelleres Delphi als 2009 oder fehlt mir was in Uses? Windows, SysUtils; habe ich momentan drinnen.
Zitat:
[DCC Error] uCharInString.pas(277): E2003 Undeclared identifier: 'rdi'
[DCC Error] uCharInString.pas(337): E2003 Undeclared identifier: 'rcx'
[DCC Error] uCharInString.pas(340): E2003 Undeclared identifier: 'r8'
[DCC Error] uCharInString.pas(341): E2003 Undeclared identifier: 'rax'
[DCC Error] uCharInString.pas(346): E2003 Undeclared identifier: 'movsxd'
[DCC Error] uCharInString.pas(349): E2003 Undeclared identifier: 'r9'
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#125

AW: Anzahl eines Zeichens im String ermitteln

  Alt 15. Jul 2018, 02:59
Wollt ihr den String nicht auch noch aufteilen und Multithreaded mit SSE/MMX/... oder besser noch mit CUDA/OpenCL/... beackern?


Zitat:
[DCC Error] uCharInString.pas(277): E2003 Undeclared identifier: 'rdi'
[DCC Error] uCharInString.pas(337): E2003 Undeclared identifier: 'rcx'
[DCC Error] uCharInString.pas(340): E2003 Undeclared identifier: 'r8'
[DCC Error] uCharInString.pas(341): E2003 Undeclared identifier: 'rax'
[DCC Error] uCharInString.pas(346): E2003 Undeclared identifier: 'movsxd'
[DCC Error] uCharInString.pas(349): E2003 Undeclared identifier: 'r9'
2009 und 64 Bit
$2B or not $2B

Geändert von himitsu (15. Jul 2018 um 03:03 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#126

AW: Anzahl eines Zeichens im String ermitteln

  Alt 15. Jul 2018, 03:08
Dann möchte ich meine schnell zusammengeschrieben Assembler-Rountine auch noch ins Rennen werfen.
Delphi 2009 verweigert mir Deinen Code. Benötige ich dafür ein aktuelleres Delphi als 2009 oder fehlt mir was in Uses? Windows, SysUtils; habe ich momentan drinnen.
Zitat:
[DCC Error] uCharInString.pas(277): E2003 Undeclared identifier: 'rdi'
[DCC Error] uCharInString.pas(337): E2003 Undeclared identifier: 'rcx'
[DCC Error] uCharInString.pas(340): E2003 Undeclared identifier: 'r8'
[DCC Error] uCharInString.pas(341): E2003 Undeclared identifier: 'rax'
[DCC Error] uCharInString.pas(346): E2003 Undeclared identifier: 'movsxd'
[DCC Error] uCharInString.pas(349): E2003 Undeclared identifier: 'r9'



PS: Wer viel misst misst Mist.
Gerade beim Selbstbau von Assemblerzeugs sollte man auch beachten, dass CPUs sich unterschiedlich verhalten.
Einige halbwegs Aktuelle planen z.B. schonmal vor und werden dann ausgebremst, wenn der Code sich anders/unvorhersehbar/abwechselnd verhält.
Ich hatte mal eine Zählschleife gebaut und bremste meine CPU so aus, dass die For-In-Schleife von Delphi doppelt so schnell lief.
$2B or not $2B

Geändert von himitsu (15. Jul 2018 um 03:12 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#127

AW: Anzahl eines Zeichens im String ermitteln

  Alt 15. Jul 2018, 06:55
screenshot-15_07.jpg So sieht mein letzter Entwurf aus.
Vorkompiliert plus Source im Anhang.
Es sind noch nicht alle Varianten enthalten, aber bitte testet mal ob das einem Benchmark gerecht wird.

Abgesehen von noch fehlender Methoden brauche ich auch Hilfe bei etwas was mir gerade den Kopf verdreht.
Delphi-Quellcode:
 if ((Tests.ItemIndex = 0) or (Tests.ItemIndex = 1)) then
  begin
    for Loops := 0 to Times.Value do
    begin
      QueryPerformanceCounter(Int64((@lpPerformanceCount1)^));
      i := CharInString.miep(Data, Ch);
      QueryPerformanceCounter(Int64((@lpPerformanceCount2)^));
      QueryPerformanceFrequency(Int64((@Frequency)^));
      Curr := (1000000 * (lpPerformanceCount2.QuadPart - lpPerformanceCount1.QuadPart) / Frequency.QuadPart);
      if Loops = 0 then
      begin
        Last := Curr;
        Min := Curr;
        Max := Curr;
        Avg := Curr;
      end;
      if Curr < Min then Min := Curr;
      if Curr > Max then Max := Curr;
      if Curr < Last then Avg := (((Curr - Last) / 2) - Avg);
      if Curr > Last then Avg := (((Curr - Last) / 2) + Avg);
      Last := Curr;
      if fCancel = True then Break;
    end;
    Avg := Abs(Avg);
    if b = False then lstResults.Items.Add(format('%.10d',[Round(Avg)])+ ' - Statistic: [ASCII Data] ['+IntToStr(Round( Min + ((Max-Min)/2) ))+' Avg] ['+IntToStr(Round(Min))+' Min] ['+IntToStr(Round(Max))+' Max] [found ' + IntToStr(Ord(Ch)) + ' = '+IntToStr(i)+' times] @ Miep()');
    if b = True then lstResults.Items.Add(format('%.10d',[Round(Avg)])+ ' - Statistic: [Binary Data] ['+IntToStr(Round( Min + ((Max-Min)/2) ))+' Avg] ['+IntToStr(Round(Min))+' Min] ['+IntToStr(Round(Max))+' Max] [found ' + IntToStr(Ord(Ch)) + ' = '+IntToStr(i)+' times] @ Miep()');
  end;
  if fCancel = True then goto cancel;
So schaut nun ein kompletter Bench-Block aus, Hilfe brauche ich bei der Berechnung der Variable "Avg". Irgendwie mache ich da etwas falsch und komme gerade nicht auf die korrekte Lösung.
Die "Avg" Variable soll den praktischen Durchschnittswert darstellen wohingegen ['+IntToStr(Round( Min + ((Max-Min)/2) ))+' Avg] den synthetischen Durchschnittswert darstellt.
Oder mache ich es bereits richtig? Mir dröhnt der Kopf. *Hilfe*

So hier sehen nun die Ergebnisse aus:
Zitat:
KodeZwerg's custom Benchmark - DP CountCharInString Edition

Benchmark: Sleep(500)
506229 Nanoseconds wasted. As closer this is to 500000 more accurate Results are given.

Benchmark: Generate Random Data String (500000 chars) Charset: [aA0-zZ9]
5977 Nanoseconds wasted.

0000000523 - Statistic: [ASCII Data] [645 Avg] [575 Min] [715 Max] [found 88 = 8068 times] @ Uwe Raabe CharCount2()
0000000764 - Statistic: [ASCII Data] [738 Avg] [724 Min] [751 Max] [found 88 = 8068 times] @ EgonHugeist EH_CharCount4()
0000000851 - Statistic: [ASCII Data] [667 Avg] [573 Min] [761 Max] [found 88 = 8068 times] @ EgonHugeist CharCount3()
0000000882 - Statistic: [ASCII Data] [602 Avg] [420 Min] [784 Max] [found 88 = 8068 times] @ EgonHugeist EH_CharCount_6()
0000001219 - Statistic: [ASCII Data] [1185 Avg] [1168 Min] [1202 Max] [found 88 = 8068 times] @ Uwe Raabe StringCountChar()
0000001222 - Statistic: [ASCII Data] [1107 Avg] [851 Min] [1363 Max] [found 88 = 8068 times] @ EgonHugeist EH_CharCount_5()
0000001352 - Statistic: [ASCII Data] [1165 Avg] [709 Min] [1620 Max] [found 88 = 8068 times] @ KodeZwerg CountCharInString()
0000001372 - Statistic: [ASCII Data] [1336 Avg] [1319 Min] [1354 Max] [found 88 = 8068 times] @ Uwe Raabe CharCount()
0000001517 - Statistic: [ASCII Data] [1426 Avg] [1161 Min] [1691 Max] [found 88 = 8068 times] @ Miep()
0000001559 - Statistic: [ASCII Data] [1423 Avg] [1168 Min] [1677 Max] [found 88 = 8068 times] @ alzaimar
0000001910 - Statistic: [ASCII Data] [1569 Avg] [1378 Min] [1760 Max] [found 88 = 8068 times] @ Missionar
0000002157 - Statistic: [ASCII Data] [1982 Avg] [1872 Min] [2092 Max] [found 88 = 8068 times] @ marabu
0000002400 - Statistic: [ASCII Data] [2062 Avg] [1889 Min] [2234 Max] [found 88 = 8068 times] @ KodeZwerg CharInStringA()
0000009962 - Statistic: [ASCII Data] [4643 Avg] [856 Min] [8430 Max] [found 88 = 8068 times] @ Neutral General CharCountAsm()
0012230425 - Statistic: [ASCII Data] [13141133 Avg] [12800203 Min] [13482064 Max] [found 88 = 8068 times] @ Ydobon
edit
Ps: Da es noch nicht Threaded kann man noch nicht Canceln !!!
Angehängte Dateien
Dateityp: 7z Benchmark.7z (219,7 KB, 4x aufgerufen)
Gruß vom KodeZwerg

Geändert von KodeZwerg (15. Jul 2018 um 07:51 Uhr)
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#128

AW: Anzahl eines Zeichens im String ermitteln

  Alt 15. Jul 2018, 10:01
Delphi 2009 verweigert mir Deinen Code. Benötige ich dafür ein aktuelleres Delphi als 2009 oder fehlt mir was in Uses? Windows, SysUtils; habe ich momentan drinnen.
Ach ja, da war doch was. Das CPUX86 DEFINE wurde ja erst später eingeführt, damit es mit dem CPUX64 harmoniert. Ersetze das
{$IFDEF CPUX86} einfach durch ein {$IFNDEF CPUX64} (Das "N" nicht vergessen)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#129

AW: Anzahl eines Zeichens im String ermitteln

  Alt 15. Jul 2018, 11:49
So schaut nun ein kompletter Bench-Block aus,
Ich finde, du machst es dir hier unnötig kompliziert und erhöhst zumindest potentiell die Messungenauigkeit in dem du die Zeit für jede einzelne Iteration misst. In jedem Fall erhöhst du aber die Gesamtlaufzeit des Benchmarks (nicht das Ergebnis), weil innerhalb der Schleife ein Haufen berechnet wird (zur Zeit offenbar auch noch falsch), der da gar nicht nötig wäre (z.B. wird der von QueryPerformanceCounter gelieferte Wert bereits beim Windows-Start festgelegt).

Aktuell schaut deine Messung so aus:
Delphi-Quellcode:
      QueryPerformanceCounter(Int64((@lpPerformanceCount1)^));
      i := CharInString.miep(Data, Ch);
      QueryPerformanceCounter(Int64((@lpPerformanceCount2)^));
Die Auflösung von QueryPerformanceCounter liegt zwar unter 1 Mikrosekunde, aber deine Messungen liegen zum Teil deutlich unter diesem Wert. Das bedeutet, daß die gemessene Laufzeit im Bereich oder sogar unter der Messgenauigkeit liegt, was einen relativ hohen Messfehler, schlimmstenfalls sogar vollkommen unbrauchbare Ergebnisse erwarten lässt.

Diesen Messfehler kannst du sehr leicht reduzieren, wenn du die Messung über eine deutlich größere Anzahl der Aufrufe machst und dann durch diese Anzahl teilst. Die gemessene Zeit sollte also mindestens 2-3 Größenordnungen über der Messgenauigkeit liegen (das wären hier 0.01 - 0.1 ms).

Aktuell versuchst du die mehrfachen Einzelmessungen zu mitteln, was dir aber nur den Mittelwert der einzelnen Fehler liefert, diesen aber nicht zwingend verkleinert (z.B. wenn er immer positiv ist).

In meinem Benchmark hatte ich das schon so implementiert. Nach dem Start der Stopwatch wird die zu messende Funktion 10000x aufgerufen und dann die Gesamtzeit gemessen. Da hier nur die Rangfolge relevant ist, spare ich mir das Runterrechnen auf die mittlere Laufzeit eines einzelnen Aufrufs. Durch diese Maßnahme haben wir den obigen Messfehler auf 1/10000 verkleinert, womit er vernachlässigbar wird.

Nun kann man argumentieren, daß die Messung über die Schleife ja auch einen gewissen Overhead verursacht. Zu diesem Zweck mache ich einen Kalibrierungslauf mit der Fake-Funktion, die in Relation zu den später zu messenden Funktionen vernachlässigbar kurz ist. Die bisherigen Läufe ergaben alle eine vernachlässigbare Laufzeit der Timing-Schleife. Gegebenenfalls kann man den hier ermittelten Wert dann auch von den späteren Messergebnissen abziehen. Bei den 10000 Aufrufen liegt der Fehler deutlich unter 1/1000.

Übrigens: Wenn deine Delphi-Version noch keine TStopwatch kennt, es gibt eine offizielle und frei verfügbare Vorgängerversion von Allen Bauer: News Flash! Someone has already invented the wheel!
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.538 Beiträge
 
Delphi 11 Alexandria
 
#130

AW: Anzahl eines Zeichens im String ermitteln

  Alt 15. Jul 2018, 12:31
Anhang 49520So in etwa würde neue GUI aussehen.
Wem noch mehr sinnvolle Optionen einfallen, bitte melden.

Edit
Ps: Ein Cancel Button ist nun vorhanden
Wenn man die zu startenden Funktionen in einer Checklist-Box zuvor auswählen könnte, fände ich gut (evtl. über Popup-Menü mit Einträgen für alle abwählen und alle anwählen). Denn wenn man an einer Funktion evtl. selber noch was rumschrauben wollte, müsste man nicht alle Tests durchlaufen lassen...

Ansonsten:
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 13 von 16   « Erste     3111213 1415     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:44 Uhr.
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