Autor Beitrag
Jelzin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 30



BeitragVerfasst: Sa 04.12.04 10:05 
Hiho Leute!

Folgendes Problem habe ich:

Ich möchte eine Textdatei in einem TRichEdit coloriert darstellen (ähnlich wie der Delphi-Editor), also farbige Zeilen, fett gedruckte Zeichen etc.
Folgende Routine verwende ich um einzelne Zeilen im RichEdit nach einem Click auf TButton farbig hervorheben zu lassen, das ganze funktioniert auch wenn die Datei die ich lade lediglich ein paar kilobyte groß ist. Interessasnt wirds wenn die Datei ca. 40 MB hat, dann braucht die FOR-Schleife Stunden! Kann mir jemand helfen das ganze so zu beschleunigen dass die Routine auch mehrere MB große Dateien schnell verarbeitet?

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
procedure TFormLogFiles.Button1Click(Sender: TObject);

// Text ist momentan in Standardschriftart, jetzt farbig machen

var
  s : string;
  i : integer;
  script : integer;

begin
  if RichEditLog.Lines.Count > 0 then
  begin
    RichEditLog.Enabled := false;
    for i := 0 to RichEditLog.Lines.Count-1 do
    begin
      s := RichEditLog.Lines[i];
      RichEditLog.Lines.Delete(i);

      script := 0;
      if pos(uppercase('Warning:'), uppercase(s))       = 1 then script := 1;
      if pos(uppercase('ScriptWarning:'), uppercase(s)) = 1 then script := 2;
      if pos(uppercase('TOST:'), uppercase(s))          = 1 then script := 3;
      if pos(uppercase('kick'), uppercase(s))          <> 0 then script := 4;
      if pos(uppercase('Log:'), uppercase(s))           = 1 then script := 5;
      if pos(uppercase('Init:'), uppercase(s))          = 1 then script := 6;
      if pos(uppercase('Exit:'), uppercase(s))          = 1 then script := 6;
      if pos(uppercase('DevNet:'), uppercase(s))        = 1 then script := 7;

      case script of
        0 : begin RichEditLog.SelAttributes.Color := clWindowText; RichEditLog.SelAttributes.Style := []; end;
        1 : begin RichEditLog.SelAttributes.Color := clred;        RichEditLog.SelAttributes.Style := []; end;
        2 : begin RichEditLog.SelAttributes.Color := clMaroon;     RichEditLog.SelAttributes.Style := []; end;
        3 : begin RichEditLog.SelAttributes.Color := clBlack;      RichEditLog.SelAttributes.Style := [fsbold]; end;
        4 : begin RichEditLog.SelAttributes.Color := clred;        RichEditLog.SelAttributes.Style := [fsbold]; end;
        5 : begin RichEditLog.SelAttributes.Color := clWindowText; RichEditLog.SelAttributes.Style := [fsitalic]; end;
        6 : begin RichEditLog.SelAttributes.Color := clBlue;       RichEditLog.SelAttributes.Style := []; end;
        7 : begin RichEditLog.SelAttributes.Color := clFuchsia;    RichEditLog.SelAttributes.Style := []; end;
      end;

      RichEditLog.Lines.Insert(i, s);

      FormLogFiles.StatusBar1.SimpleText := IntToStr(i+1)+' of '+IntToStr(RichEditLog.Lines.Count)+' processed';
      Application.ProcessMessages;
    end;
    RichEditLog.Enabled := true;
  end;
end;
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 04.12.04 10:48 
Lass mal das Application.ProcessMessages raus und die ausgabe in der Statusbar. Das sollte schon einiges bringen.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Sa 04.12.04 11:09 
Titel: Vorschlag zur Struktur
Moin!

Hm, ich kenne mich nicht soo gut mit TRichEdit aus, aber von der Programmstruktur her würde ich folgende Vorschläge machen wollen:

1. du "schaufelst" Speicherblöcke durch die Gegend (Zeile in lokalen String kopieren, Ausschneiden, ändern, wieder einfügen); das ist bei kleinen Textdateien sicherlich OK, aber wenn es sich um SEHR VIELE Zeilen handelt, kann das ordentlich auf die Performance gehen. Ich weiß zugegebenermaßen nicht, ob oder wenn, wie, das geht, aber es wäre sicherlich besser, wenn du die Attribute ohne neues Anlegen der Zeilen setzen würdest.

2. Eine Möglichkeit den ersten Vorschlag umzusetzen wäre, die Datei nicht zuerst ganz in den Speicher zu lesen, sondern nur in Teilen und diese Teile dann mit deinem Code in das RichEdit zu "übersetzen". Stichwort: Filter.

3. Den Application.ProcessMesages() hast du drin, damit die Anwendung "benutzbar" bleibt, während der Text umgesetzt wird. Nimmst du den Aufruf raus, läuft es sicherlich schneller (wie Luckie empfohlen hat), aber dafür "steht" die Anwendung in dieser Zeit auch. Deshalb wäre es sicher schlau, das RichEdit zu disabeln und einen Thread zu starten, der die "Textumwandlung" vornimmt und dann wieder abstirbt. Wenn der Thread terminiert, enablest du das RichEdit wieder. Fertig.

cu
Narses
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 04.12.04 11:15 
Genau, warum löscht du die Zeile eigentlich und fügst sie wieder ein? Wwarum arbeitest du nicht mit SelStart und SelLength?
AXMD
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Sa 04.12.04 11:29 
Außderdem gibts noch SynEdit - damit musst du nicht allzuviel um den Code kümmern

AXMD
Jelzin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 30



BeitragVerfasst: Sa 04.12.04 12:03 
SelStart und SelEnd hat die unangenehme Eigenschaft dass man die genaue Position herausfinden muss an der nach SelTextAttributes wirkt. Damit wird der ganze Quelltext wesentlich komplizierter und nur bedingt schneller. Also keine richtige Lösung für mein Problem.
Die Zeile muss ich löschen und wieder einfügen damit sie nachher neu formatiert wieder sichtbar wird.

Könnt mir jemand mit dem Threat-Vorschlag ein Beispiel geben? Mit Threats hab ich noch nie gearbeitet und kenn mich relativ wenig damit aus :?

P.S.: Ich leg bei dem Programm ziemlich viel Wert darauf dass nirgends der Anschein erweckt wird die Application sei eingefroren. Auch wenns die Performance ohne Application.ProcessMessages erhöhen würde.

Danke für die schnellen Antworten!!
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 04.12.04 12:12 
Jelzin hat folgendes geschrieben:
SelStart und SelEnd hat die unangenehme Eigenschaft dass man die genaue Position herausfinden muss an der nach SelTextAttributes wirkt. Damit wird der ganze Quelltext wesentlich komplizierter und nur bedingt schneller.

Das glaube ich eigentlich nicht.

Thread Tutorial: tutorials.luckie-online.de oder kurze Demo Anwendung: www.luckie-online.de...d_mit_Nachricht.html
AXMD
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Sa 04.12.04 12:13 
Nur ein Hinweis nebenbei:

Threat heißt Bedrohung; was du meinst sind Threads. Müsste es aber im Forum genug zu finden geben (Suche in: Delphi-Forum, Delphi-Library THREAD).

AXMD
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 04.12.04 12:24 
AXMD hat folgendes geschrieben:
Threat heißt Bedrohung; was du meinst sind Threads.

Freud'sche Fehlleistung. Für so manchen stellen sie bestimmt ein programmiertechnische Bedrohung dar. ;)
AXMD
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Sa 04.12.04 12:44 
Luckie hat folgendes geschrieben:
AXMD hat folgendes geschrieben:
Threat heißt Bedrohung; was du meinst sind Threads.

Freud'sche Fehlleistung. Für so manchen stellen sie bestimmt ein programmiertechnische Bedrohung dar. ;)


:lol:

AXMD
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Sa 04.12.04 13:15 
Titel: Code-Komplexität
Moin!

Jelzin hat folgendes geschrieben:
Damit wird der ganze Quelltext wesentlich komplizierter und nur bedingt schneller. Also keine richtige Lösung für mein Problem.

Hopla, gemach. Komplexer Code ist nicht automatisch langsam! Sobald du Calls im Code hast, wird es praktisch sowieso nicht mehr ohne Hilfsmittel möglich, das Laufzeitverhalten zu beurteilen. Dann kommen noch Caching-Aspekte der Hardware hinzu und so weiter...
Generell läßt sich aber sicherlich sagen, dass Code, der viele Daten modifiziert bzw. "bewegt", überlicherweise langsamer ist als Code, der "sucht". Von dieser Annahme ausgehend ist es bestimmt effizienter, zunächst die korrekten Positionen für eine Änderung zu bestimmen und dann nur das Notwendige zu ändern.

Wenn du allerdings annimmst, dass dein Code zur Verwendung von SelStart und SelEnd nicht effizient ausfallen würde, empfehle ich dir den Filter-Ansatz zu verfolgen. Ich würde mir das in etwa so vorstellen:
- Datei "stückweise" einlesen
- Stücke durch den Code laufen lassen, der die Formatierung vornimmt und dabei ins RichEdit schreiben
- wiederholen, bis alle Stücke gelesen sind

Wenn du voraussetzen kannst, dass bei ALLEN Anwendern "genug" Speicher vorhanden ist, kannste die Textdatei auch komplett in eine TStringList einlesen und dann ins RichEdit überführen ("filtern"). Vorsicht! Min. doppelter Speicherbedarf!

Diesen Filter dann als Thread auszuführen ist natürlich noch eine andere Aufgabe... :wink:

cu
Narses
Jelzin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 30



BeitragVerfasst: Sa 04.12.04 17:14 
Ok :) Danke für die Hilfe. Die bringt mich weiter. Mit SynEdit beschäftig ich mich auch noch ein bissl, aber das scheint umfangreicher zu werden.