AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Diese funktion schneller machen?

Ein Thema von Pseudemys Nelsoni · begonnen am 29. Okt 2004 · letzter Beitrag vom 2. Nov 2004
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von Nothine
Nothine

Registriert seit: 3. Jul 2004
Ort: Mülheim an der Ruhr
198 Beiträge
 
Delphi 5 Enterprise
 
#11

Re: Diese funktion schneller machen?

  Alt 30. Okt 2004, 10:11
weil S := PChar(Text) intern LStrToPChar aufruft, S := Pointer(Text) dagegen übergibt wirklich nur die adresse von @Text[1] an S
if ThisPost is senseless then
ThisPost.WasPostedBy := SomeoneElse();
  Mit Zitat antworten Zitat
GaP

Registriert seit: 29. Okt 2004
2 Beiträge
 
Delphi 7 Enterprise
 
#12

Re: Diese funktion schneller machen?

  Alt 30. Okt 2004, 10:25
Hi,

ich stell einfach mal die Funktion mit der ich solche Aufgaben erledige in den Raum, ob sie schneller ist oder nicht kann ich nicht sagen, vllt. kann ja noch jemand Tipps geben...

Delphi-Quellcode:
function W(Wort: Integer; Text, Zeichen: String): String;
var Anfang, Ende, i: Integer;
begin
  Anfang := 0;
  Ende := 0;
  if Pos(Zeichen, Text) = 0 then Result := 'else begin
    if Wort = 1 then begin
      Anfang := Pos(Zeichen, Text);
      Result := MidStr(Text, 1, Anfang-1);
    end
    else begin
      for i:=1 to Wort-1 do Anfang := PosEx(Zeichen, Text, Anfang+1);
      if PosEx(Zeichen, Text, Anfang+1) = 0 then Ende := Length(Text)
      else Ende := PosEx(Zeichen, Text, Anfang+1)-Anfang-1;
      Result := MidStr(Text, Anfang+1, Ende);
    end;
  end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#13

Re: Diese funktion schneller machen?

  Alt 30. Okt 2004, 10:54
@Nothine: tja, das sind solche internen Änderungen zwischen den einzelnen Delphi Versionen. Bis Delphi 5 bin ich mir sicher das intern PChar(String) identisch zu Pointer(String) ist. Wenn aber in Delphi 7 intern LStrToPChar() aufgerufen wird dann muß das seine Gründe haben. Da wir unbedingt einen 0-terminierten PChar benötigen würde ich es so lassen wie es ist. Einfach der Kompatibilität halber.

Grundsätzlich dürfte damit meine Funktion nicht wesentlich langsammer werden, und davon mal abgesehen ist sie um vielfaches schneller als alle Varianten die mit Pos(), PosEx(), MidStr(), Delete() usw. arbeiten. Und meiner Meinung nach sogar viel einfacher zu verstehen

Gruß Hagen
  Mit Zitat antworten Zitat
DeerHunter

Registriert seit: 8. Jun 2004
16 Beiträge
 
Delphi 6 Professional
 
#14

Re: Diese funktion schneller machen?

  Alt 30. Okt 2004, 11:05
mal eine Frage am Rande: wo ist der unterschied zwischen Pos und PosEx? letzteres scheint es wohl erst ab Delphi 7 zu geben, oder?
  Mit Zitat antworten Zitat
Benutzerbild von Nothine
Nothine

Registriert seit: 3. Jul 2004
Ort: Mülheim an der Ruhr
198 Beiträge
 
Delphi 5 Enterprise
 
#15

Re: Diese funktion schneller machen?

  Alt 30. Okt 2004, 11:12
@Hagen: klar, ich sag ja auch gar nichts gegen deine funktionen, du bist der profi hier, nich ich und es ging ja auch nur darum wie man es schneller macht, und eine einfache pointerzuweisung is nu ma schneller und ich glaube ich muss dich enttäuschen, aber die information das intern LStrToPChar aufgerufen wird habe ich gerade eben meinem delphi 5(!) entnommen

@DeerHunter: jap, PosEx is erst später hinzugekommen und definiert zusätzlich einen start-offset, bei dem die suche beginnt
if ThisPost is senseless then
ThisPost.WasPostedBy := SomeoneElse();
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#16

Re: Diese funktion schneller machen?

  Alt 30. Okt 2004, 11:33
Stimmt, habe gerade nochmal in die RTL reingeschaut

Allerdings muss PChar(String) dann benutzt werden, denn wenn Pointer(String) == NIL ist, wandelt _LStrToPChar() -> PChar(String) diesen NIL Zeiger in einen Zeiger auf einen PChar mit Null-Terminator um.
Wenn man also Pointer(String) benutzen will so muß man danach zusätzlich abfragen ob dieser Zeiger NIL ist. Dies wird dann aber wirklich nur 4-8 CPU Takte schneller sein als ein PChar(String).

Es lohnt also nicht sich vom "Standardkonformen" Weg zu entfernen und Pointer(String) statt PChar(String) zu benutzen.

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von Nothine
Nothine

Registriert seit: 3. Jul 2004
Ort: Mülheim an der Ruhr
198 Beiträge
 
Delphi 5 Enterprise
 
#17

Re: Diese funktion schneller machen?

  Alt 30. Okt 2004, 11:40
okok, weniger tippen müsste man natürlich bei S := PChar(Text), andererseits stellt sich die frage ob man nicht eh am anfang der routine prüft ob Text = '', weil was will man aus einem leeren string schon an tokens oder indizes auslesen?
if ThisPost is senseless then
ThisPost.WasPostedBy := SomeoneElse();
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#18

Re: Diese funktion schneller machen?

  Alt 30. Okt 2004, 12:36
Ja, man könnte jeden Spezialfall mit einer eigenen Abfrage programmieren. Ich persönlich hasse das aber. Lieber die Funktionen so allgemein, kurz und schnell wie möglich halten.
Zb. in meinem obigem Vorschlag würde bei Text = '';

while (S^ <> #0) ... do; schon zuschlagen. D.h. eine einzigste Abfrage. Dann weiter:

Delphi-Quellcode:
D := S;
while (D^ <> #0) do ;
eine Zuweisung -> "MOV Reg1, reg2" und eine Abfrage wiederum.
Und am Schluß

  SetString(Result, S,D - S); eine Subtraktion "SUB ECX,EDX"und ein CALL _SetLength(EAX, EDX, ECX);

Damit ist der UNWAHRSCHEINLICHSTE Fall, das Text == '' ist, genügend abgedeckt. Viel wahrscheinlicher sind aber Strings <> '', und somit würde eine ständige vorherige und spezielle Abfrage auf Text = '' eher bremsen als sinnvoll sein.

Programmiere immer nur soviel wie absolut nötig ist, verkompliziere nicht die Logik mit Abfragen die vom Programmfluß eher am unwahrscheinlichsten sind. Als Resulat kommt eine Lösung heraus die man leicht versteht und gut optimiert und denoch kurz und bündig ist.

Momentan sehe ich echt keinen Grund bzw. weitere Möglichkeit meine Funktion weiter zu verbessern.

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von Nothine
Nothine

Registriert seit: 3. Jul 2004
Ort: Mülheim an der Ruhr
198 Beiträge
 
Delphi 5 Enterprise
 
#19

Re: Diese funktion schneller machen?

  Alt 30. Okt 2004, 13:21
obwohl sie gegen ende umständlicher aussieht, ist diese
Delphi-Quellcode:
function ExtractToken(const Text: string; Index: Integer; const Separator: Char = ' '): string;
var S,D: PChar;
begin
  S := PChar(Text);
  while (S^ <> #0) and (Index > 0) do begin
    if S^ = Separator then Dec(Index);
    Inc(S);
  end;
  D := S;
  while (D^ <> #0) and (D^ <> Separator) do Inc(D);
  SetLength(Result,D-S);
  D := Pointer(Result);
  while (S^ <> Separator) and (S^ <> #0) do begin
    D^ := S^;
    Inc(S);
    Inc(D);
  end;
end;
funktion auf meinem system bei 10000000 wiederholungen ca. 600 millisekunden schneller, bitte um test deinerseits

edit: nur noch zur info, zeitversuch nach dem GetTickCount-prinzip
if ThisPost is senseless then
ThisPost.WasPostedBy := SomeoneElse();
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#20

Re: Diese funktion schneller machen?

  Alt 30. Okt 2004, 14:31
probier mal

Delphi-Quellcode:
  R := Pointer(Result);
  while S < D do
  begin
    R^ := S^;
    Inc(S);
    Inc(R);
  end;

// oder
  
  R := Pointer(Result);
  for I := 0 to D - S -1 do
    R[I] := S[I];
Das SetString() langsammer sein kann auf modernen CPU's im Gegensatz zu einer eigenen Loop kann durchaus so sein. Allerdings beachte das du mit dynamisch allozierten Strings arbeitest, und dein Test eventuell immer wieder die gleichen Speicherbereiche benutzt da der Speicher Manager so arbeitet. In einem solchen Falle, und nur in einem solchen Fall, kann eine einfache Loop schneller sein als das REP MOVSW in Copy()->SetString().
Du solltest also deine Tests so aufbauen das nacheinander, sozusagen verschachtelt immer wieder neue Speicherbereiche alloziert werden. Zudem solltest du die Funktion INNERHALB von vielen anderen Funktionen testen. Also simulierst du die wahrscheinlichst realen Bedingungen der Anwendung der Funktion innerhalb eines Programmes. Ich vermute das du einfach in deinen Tests in einer Schleife die Funktion mit den gleichen Daten aufgerufen hast. Solche Test sagen fast garnichts über die realen Verhältnisse der Funktion in realen Programmen aus.

Gruß Hagen
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 02:05 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