AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Warum ist das Löschen einer Zeile aus einer Memo so langsam?

Warum ist das Löschen einer Zeile aus einer Memo so langsam?

Ein Thema von Der schöne Günther · begonnen am 25. Mär 2013 · letzter Beitrag vom 26. Mär 2013
Antwort Antwort
Seite 2 von 2     12
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#11

AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?

  Alt 26. Mär 2013, 12:40
Aber warum ist es dann so blitzschnell wenn ich im Endeffekt ein
  • Setze Cursor nach ganz oben
  • Markiere die ersten 400 Zeilen
  • Entferne sie

mit der mysteriösen Perform() -Methode (siehe erster Beitrag) ausführe?
Weil dann nur eine Aktualisierung ausgelöst wird und weil ein TMemo keine TStringList hat, sondern der Inhalt irgendwie als TStrings veröffentlicht wird. Je nachdem, wie dieses implementiert ist, geht das eben langsam oder schnell

Ich vermute mal dass bei deinem Delete 400x diese Perform Funktion aufgerufen wird und das BeginUpdate, EndUpdate hier nicht greift
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (26. Mär 2013 um 12:42 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.083 Beiträge
 
Delphi 10.3 Rio
 
#12

AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?

  Alt 26. Mär 2013, 13:36
Ein Blick in die StdCtrls.pas wirkt manchmal Wunder (TCustomMemo.Lines ist vom Typ TMemoStrings, Zitat vorsichtshalber gekürzt):
Zitat:
Delphi-Quellcode:
procedure TMemoStrings.Delete(Index: Integer);
begin
  ... SendMessage(Memo.Handle, EM_LINEINDEX, Index, 0);
  ...
    ... SendMessage(Memo.Handle, EM_LINEINDEX, Index + 1, 0);
    if ... then
      SendMessage(Memo.Handle, EM_LINELENGTH, SelStart, 0);
    SendMessage(Memo.Handle, EM_SETSEL, SelStart, SelEnd);
    SendTextMessage(Memo.Handle, EM_REPLACESEL, 0, '');
  end;
end;
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Horst_

Registriert seit: 22. Jul 2004
Ort: Münster Osnabrück
116 Beiträge
 
#13

AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?

  Alt 26. Mär 2013, 14:14
Hallo,

ich habe es mal mittels Lazarus unter Linux probiert und dort funktioniert memo1.lines.delete(0) sehr schnell.
Unter Win7 wurde es elend langsam.Warum, haben ja BUG und DeddyH aufgezeigt.
Amateurprofi's Ansatz ist etwas kryptisch. Ich habe Jaenicke's Idee aufgegriffen und das ist auch recht schnell und hoffentlich lesbar.
Delphi-Quellcode:
const
  MaxLineCnt = 5000;
  DelFirst = 400;
procedure Tform1.Memofuellen(Sender: TObject);
var
   Formtxt : string;
   i,k : integer;
   TmpList : TStringList;
begin
  //Irgendeinen Text erzeugen mit laufender Nummer vorweg
  Formtxt :='%.8d';
  k := 64;
  i := length(Formtxt);
  Setlength(Formtxt,i+k);
  repeat
    inc(i);
    FormTxt[i] := chr(k+32);
    dec(k);
  until k < 0;

  i := MaxLineCnt;
  TmpList := TStringList.create;
  with TmpList do begin
    BeginUpdate;
    Capacity:= i;
    while i >= 1 do begin
      Add(Format(Formtxt,[i]));
      dec(i);
      end;
    EndUpdate;
    end;
  Memo1.lines := TmpList;
  TmpList.Free;
end;

procedure MemoZeilenentfernen( Ab,Anzahl:integer;var Mem:TMemo);
var
  i,k : integer;
  TmpList : TStringList;
begin
  TmpList := TStringlist.create;
  try
    With TmpList do begin
      AddStrings(mem.lines);
      k := Ab;
      i := Ab+Anzahl;
      // Ueber das Ende hinaus, dann begrenzen
      IF i > count then
        i := count;

      Beginupdate;
      while i < Count do begin
        Exchange(k,i); //Zeigertausch
        inc(k);
        inc(i);
        end;
      //Loeschen von oben nach unten
      while i > k do begin
        dec(i);
        delete(i);
        end;
      EndUpdate;
      end;

    Mem.Lines := TmpList;
  finally
    TMPList.free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  T1,T0: TDateTime;
begin
   IF Memo1.lines.count = 0 then
     Memofuellen(self);
   IF memo1.lines.count<=DelFirst then begin
     memo1.lines.clear;
     EXIT;
     end;

   T0 := now;
   MemoZeilenentfernen( 0,DelFirst,memo1);
   T1 := now;

   Edit1.text := FormatDateTime('HH:NN:SS.zzz',T1-T0);
end;
Das funktioniert dann auch in unter 0.1 Sekunden statt 4,67 Sekunden mit 400-fachen memo1.lines.delete(0)

Gruß Horst
Update:
Ich habe mal eine ausgelagerte Prozedur daraus gemacht, mit der man auch innere Blöcke von Zeilen entfernen kann.
Bei Test mit 1e5 Zeilen dauerte die Übergabe an die Stringliste TmpList.AddStrings(memo1.lines) 1 Sekunde und das Löschen der ersten 400 Zeilen selbst unter 1 ms.
Man sollte also vielleicht generell die Daten in er seperaten Stringliste halten.

Geändert von Horst_ (26. Mär 2013 um 15:39 Uhr) Grund: Leichte Verbesserung
  Mit Zitat antworten Zitat
terence14
(Gast)

n/a Beiträge
 
#14

AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?

  Alt 26. Mär 2013, 14:29
Aber warum ist es dann so blitzschnell wenn ich im Endeffekt ein
  • Setze Cursor nach ganz oben
  • Markiere die ersten 400 Zeilen
  • Entferne sie

mit der mysteriösen Perform() -Methode (siehe erster Beitrag) ausführe?
Weil nach jedem Löschen einer Zeile eine Nachricht verschickt wird.
Du kannst das mit Memo1.BeginUpdate vor dem zeilenweisen Löschen und Memo1.EndUpdate wenn alle Zeilen gelöscht wurden, unterdrücken.

MfG,
terence
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.083 Beiträge
 
Delphi 10.3 Rio
 
#15

AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?

  Alt 26. Mär 2013, 14:31
Ein bisschen spät, gell?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 15:23 Uhr.
Powered by vBulletin® Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2020 by Daniel R. Wolf