![]() |
Warum ist das Löschen einer Zeile aus einer Memo so langsam?
Hallo-
Ich wundere mich:
Gibt es keine bessere Methode, die ersten x Strings aus einem
Delphi-Quellcode:
-Objekt zu entfernen?
TStrings
Entferne ich die ungewollten Zeilen folgendermaßen ist die Sache blitzschnell erledigt:
Delphi-Quellcode:
Warum ist das so?
with someMemo do
if Lines.Count > logMemoMaxLines then begin Lines.BeginUpdate(); SelStart := 0; // Quelle: http://borland.newsgroups.archived.at/public.delphi.rtl.win32/200609/0609161352.html SelLength := Perform(EM_LINEINDEX, logMemoMaxLinesClear, 0); SelText := ''; Lines.EndUpdate(); end; |
AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?
Afaik ist Lines von TMemo keine TStringList. Anstelle dessen werden jedes mal
![]() |
AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?
Warum genau das so ist, weiß ich auch nicht, aber ich kann aus Erfahrung sagen, dass TMemo z.B. auch extrem langsam wird, wenn man sehr lange Texte dort reinlädt.
Vielleicht liegt es daran, dass Memo für Windows das gleiche ist wie ein Edit... d.h. der Inhalt ist eigentlich ein einziger String und es ist daher nicht wirklich zeilenorientiert. Wahrscheinlich muss Windows beim Memo den ganzen String ständig immer wieder von vorne durchscannen, um die Zeilenvorschübe zu finden. Ist aber reine Mutmaßung meinerseits. Besser bedient ist man mit einem TRichEdit, bei dem die Eigenschaft Plain auf True gesetzt ist. |
AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?
Ich war bislang sehr zufrieden (auch bei mehreren tausend Zeilen), nur das Löschen ist katastrophal.
|
AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?
Zitat:
und mit Begin/Endupdate wird statt 400* die aktion nur einmal aufgeführt. WEnn nun jedes Aktualisieren 0,25 ms dauert kommst du auf deine Sekunde. |
AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?
Wenn mich meine Erinnerungen nicht trügen, dann hat schon das
Delphi-Quellcode:
selbst so lange gebraucht, obwohl das
Delete()
Delphi-Quellcode:
noch gar nicht kam. Ich könnte mich aber auch irren. :oops:
EndUpdate()
Kann das jemand reproduzieren? Einfach ein paar hundert Zeilen in ein Memo kloppen und dann die vorderen mittels
Delphi-Quellcode:
entfernen - Das ist doch ein schlechter Witz wie lange das dauert...
Delete()
|
AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?
Vielleicht so:?
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var i:integer; begin Memo1.Clear; Memo1.Lines.BeginUpdate; for i:=1 to 10000 do Memo1.Lines.Add('Test '+IntToStr(i)); Memo1.Lines.EndUpdate; end; procedure TForm1.Button2Click(Sender: TObject); const cr=#13; lf=#10; var count:integer; p,p1:PChar; begin if Memo1.Text='' then exit; p:=PChar(Memo1.text); p1:=p; count:=0; repeat case p^ of cr : begin inc(p); if p^=lf then inc(p); inc(count); end; lf : begin inc(p); inc(count); end; else inc(p); end; until (p^=#0) or (count=400); if p^=#0 then begin Memo1.Text:=''; end else begin count:=(NativeInt(p)-NativeInt(p1)) div SizeOf(char)+1; Memo1.Text:=Copy(Memo1.Text, count,maxint); end; end; |
AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?
Zitat:
Ein visuelles Control wie ein TMemo ist nun einmal nicht zur Datenhaltung oder -bearbeitung gedacht, sondern nur zur Anzeige und Eingabe. |
AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?
Zitat:
Gruß K-H |
AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?
Aber warum ist es dann so blitzschnell wenn ich im Endeffekt ein
mit der mysteriösen
Delphi-Quellcode:
-Methode (siehe erster Beitrag) ausführe? :|
Perform()
|
AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?
Zitat:
Delphi-Quellcode:
keine
TMemo
Delphi-Quellcode:
hat, sondern der Inhalt irgendwie als
TStringList
Delphi-Quellcode:
veröffentlicht wird. Je nachdem, wie dieses implementiert ist, geht das eben langsam oder schnell ;)
TStrings
Ich vermute mal dass bei deinem Delete 400x diese Perform Funktion aufgerufen wird und das BeginUpdate, EndUpdate hier nicht greift |
AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?
Ein Blick in die StdCtrls.pas wirkt manchmal Wunder (TCustomMemo.Lines ist vom Typ TMemoStrings, Zitat vorsichtshalber gekürzt):
Zitat:
|
AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?
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:
Das funktioniert dann auch in unter 0.1 Sekunden statt 4,67 Sekunden mit 400-fachen memo1.lines.delete(0)
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; 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. |
AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?
Zitat:
Du kannst das mit Memo1.BeginUpdate vor dem zeilenweisen Löschen und Memo1.EndUpdate wenn alle Zeilen gelöscht wurden, unterdrücken. MfG, terence |
AW: Warum ist das Löschen einer Zeile aus einer Memo so langsam?
Ein bisschen spät, gell? :mrgreen:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:36 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz