Toon posts:

[Delphi 5] Updating RichEdit zeer traag

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik gebruik een RichEdit om sourcefiles te laten zien.

De sourcefile wordt in de richedit geladen.
Vervolgens word de sourcefile in een string (s_FileContent) gelezen.

Dan worden er verschillende bewerkingen uitgevoerd op de sourcefile (s_FileContent).

Na deze bewerkingen wil ik de veranderde source weer laten zien in de RichEdit.
Dit doe ik nu als volgt:

SourceRichEdit.Lines.Text := s_FileContent;

Probleem is, dat dit erg lang duurt bij grotere files.
file met 5000 regels duurt 2 seconden
file met 17000 regels duurt bijna 20 seconden

BeginUpdate en EndUpdate helpen ook niet.

Is er iemand die een snellere manier kent om een RichEdit te updaten?

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 30-08 17:59

Gerco

Professional Newbie

Misschien is het een idee om niet alles te updaten, maar alleen de regels die ook echt in de richedit te zien zijn (plus een stuk of 50 voor een voorsprong) en dan in een achtergrondthread op je gemakkie het werk af te maken.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Weet het niet zeker, maar misschien gaan streams sneller?

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 30-08 17:59

Gerco

Professional Newbie

Hoe lang duren die bewerkingen van je? Misschien is het wel helemaal niet de richedit die traag is, maar je bewerkingen...

Als het wel de richedit is, zie je ook een vertraging bij het eerste inladen van de file, waarom lees je die eerst in trouwens, is het geen idee om de tekst maar 1x in de edit te gooien. Op deze manier is de eerste keer inlezen volkomen overbodig.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Verwijderd

Topicstarter
Het programma moet gaan dienen als sourcecode alligner. Het gaat gebruikt worden om de interne code conventie hier op mijn werk toe te passen op alle sourcefiles.
Elke sourcefile word uitgelijnd en alle Gereserveerde woorden van Delphi + variabele namen worden gecheckt op het goede gebruik van hoofdletters.

De bewerking hiervan duurt voor een file met 5000 regels 490 ms. File met 17000 regels duurt 5 seconden.

Het ligt niet aan de bewerkingen. Deze staan los van het updaten van de richedit. De RichEdit wordt pas ge-update nadat alle bewerkingen zijn uitgevoerd.

Het inladen van de file duurt niet zo lang. File met 17000 regels is binnen 2 seconden geladen in de RichEdit. Ik zal eens kijken hoe LoadFromFile precies werkt.

Verwijderd

Doe je nog bepaalde handelingen bij de OnChange?
Waarschijnlijk is via stream laden ook sneller. Je zou trouwens kunnen profilen en kijken welke actie het langst duurt:

www.prodelphi.de

Aanrader!

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

TStrings.Text is niet echt snel voor de acties die jij wilt uitvoeren.
Intern wordt het namelijk opgeslagen als een lijst van strings (in een array in het geval van een TStringList, bij een TRichEdit door windows, maar ook regel voor regel) en bij het lezen van de Text property gaat ie alle strings 1 voor 1 af en plakt ze achterelkaar. Bij het schrijven deelt ie de lange string allemaal weer op in regels. Dat zijn heel veel acties en gekopieer en is dus langzaam voor grote aantallen.

LoadFromStream van een TStrings doet hetzelfde dus zal geen verbetering opleveren. De LoadFromStream van een TRichEdit is anders geimplementeerd, maar ik kan niet precies volgen of het sneller is of niet. Testen.

Het beste en snelste lijkt mij als je direct de TStrings kunnen gebruikt ipv 1 string die je uit TStrings.Text haalt. Dan wordt er niets gecopieerd wat wel gebeurd als jij het in een string zet, maar gebruik je het object direct. Plus dat je meteen de mogelijkheden die een TStrings aanbied kan gebruiken.

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Topicstarter
LordLarry schreef op 04 oktober 2002 @ 12:51:
Het beste en snelste lijkt mij als je direct de TStrings kunnen gebruikt ipv 1 string die je uit TStrings.Text haalt. Dan wordt er niets gecopieerd wat wel gebeurd als jij het in een string zet, maar gebruik je het object direct. Plus dat je meteen de mogelijkheden die een TStrings aanbied kan gebruiken.
Dit is veel trager als het werken met een grote string. En de functies van TStrings zijn ook veel te traag.
Ik haal de filecontent ook niet uit TStrings.Text, maar lees deze apart uit de file, omdat dit vele malen sneller is.

  • Hoppie
  • Registratie: Februari 2001
  • Niet online
Heb wel 's een tabel gevuld met data. Duurde verschrikkelijk lang, totdat ik 'm onzichtbaar maakte, de tabel vulde en 'm toen weer zichtbaar maakte. Scheelde een slok op een borrel.
Misschien kun je dat 's proberen?

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Ja, dat is ook sneller natuurlijk. Ik had het beter moeten lezen dat dat het enige was wat je deed. Blijft staan dat TStrings.Text langzaam is en dat je dat zo weinig mogelijk moet gebruiken. Ik denk dan dat alleen LoadFromStream als enige overblijft als snellere mogelijkheid. TStringStream of TMemoryStream.

We adore chaos because we like to restore order - M.C. Escher


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Hoppie schreef op 04 oktober 2002 @ 13:06:
Heb wel 's een tabel gevuld met data. Duurde verschrikkelijk lang, totdat ik 'm onzichtbaar maakte, de tabel vulde en 'm toen weer zichtbaar maakte. Scheelde een slok op een borrel.
Misschien kun je dat 's proberen?
Daarvoor heb je meestal BeginUpdate en EndUpdate. In het geval van TDatasets (TTable, TQuery) en data-aware controls (TDBGrid) zet je TDataSet.DisableControls en TTable.EnableControls.

We adore chaos because we like to restore order - M.C. Escher


  • Hoppie
  • Registratie: Februari 2001
  • Niet online
LordLarry schreef op 04 oktober 2002 @ 13:11:
[...]


Daarvoor heb je meestal BeginUpdate en EndUpdate. In het geval van TDatasets (TTable, TQuery) en data-aware controls (TDBGrid) zet je TDataSet.DisableControls en TTable.EnableControls.
Zou kunnen. Ik had het probleem in National Instruments CVI. Daar hielp het.

Verwijderd

Topicstarter
Ik heb inmiddels een zeer snelle oplossing gevonden. Ik begrijp niet helemaal waarom het werkt, maar het werkt. De RichEdit toont de update nu in alle gevallen binnen 2 seconden (ook voor de file met 17000 regels).

Dit is de oplossing:

SourceRichEdit.Lines.Clear();
SendMessage(SourceRichEdit.Handle, EM_SETSEL, 0, 0);
SendMessage(SourceRichEdit.Handle, EM_REPLACESEL, 0,LongInt(s_FileContent));

Als iemand mij precies kan uitleggen hoe dit werkt, graag.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

The EM_REPLACESEL message replaces the current selection in an edit control with the specified text. You can send this message to either an edit control or a rich edit control.

Tis gewoon een opdracht om alle geselecteerde tekst te vervangen in 1x. Je omzijlt dus de TStrings.Text implementatie die het zin voor zin doet zoals ik al aangaf.

Remarks

Use the EM_REPLACESEL message to replace only a portion of the text in an edit control. To replace all of the text, use the WM_SETTEXT message.

Je kan ook WM_SETTEXT gebruiken om alle tekst te vervangen. Dan hoef je niet eerste de selectie op alles te zetten.


Bron: msdn.micrsoft.com What else?!

We adore chaos because we like to restore order - M.C. Escher

Pagina: 1