TStringlist, THashedStringlist gibts nichts schnelleres??
Hallo DPler,
TStringlist, THashedStringlist gibts nichts schnelleres?? und genauso komfortables. Ich meine die Funktionen Stringlist.LoadfromFile .SavetoFile .Strings[i]. |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Zitat:
Und bei der THashedStringList muß zusätzlich noch pro String ein Hash beechnet werden. .Strings[i] ist bei der "normalen" StringList oder bei einem Array am schnellsten, da man dort direkt via Index zugreifen kann. Bei der HashedStringList, SkipList und ihren Verwandten kommt es dann darauf an, ob neben der HashMap auch noch eine Index-Liste existiert. Das schnellste LoadfromFile wäre alles in EINEN String oder einen MemoryStream zu lesen, aber dann gibt es keinen Index und man kann nicht direkt via .Strings[i] zugreifen. PS: Wenn nur via .Strings[i] zugegriffen wird, dann ist die THashedStringList vollkommen überflüssig, weil sie auf eine Stringsuche ausgelegt ist und nicht für einen Indexzugriff. |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Natürlich gibt es die vielbeschworene Skiplist. Diese würde sogar (vgl. Suchverfahren mit Beispielen) meine Dateigröße abdecken( ca.40 000 Datensätze) aber wie verwende ich die Skiplist. In allen Beispielen wird die Skiplist mit Zufallsstrings aufgefüllt aber nie mit echten Daten.
Also wie bekomme ich eine Datei in die Skiplist (LoadfromFile) und wie kann ich mit der Skiplist arbeiten (Strings[i]) und wie Speichere ich die Daten der Skiplist (SaveToFile). |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Zitat:
Wenn du nur .LoadFromFile .SavetoFile und .Strings[i] verwendest, dann ist TStringList mitunder das Schnellste. Schneller geht es nur (wenn die Liste nicht im Programm verändert werden soll oder wenn SaveToFile etwas länger dauern darf), wenn man alles an einem Stück einließt und dann nur eine Indexliste mit den Stringanfängen/-längen anlegt und wenn auf alle Strings/Zeilen maximal ein-/zweimal zugegriffen wird oder wenn einem der Speicherverbrauch für eine doppelte Datenhaltung egal ist. |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Zitat:
|
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Wenn du "sehr oft" etwas ändern/einfügen/löschen und auch sortieren würdest und "selten" via .Strings[i] zugreifst, dann wäre eine HashList ('ne SkipList ist auch eine) insgesamt schon schneller. :angel2:
|
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Ich benötige die Stringliste nur zum sortieren,laden,speichern und sehr häufig die .Strings[i] Funktion. Das sortieren benötigt die geringste Zeit, es wäre schon ein erheblicher Fortschritt wenn es einen Weg gäbe der die .Strings[i] Verarbeitung beschleunigen würde.
|
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Delphi-Quellcode:
Wie gesagt, .Strings von TStringList (TStrings) ist schon ein direkter Zugriff und schneller als direkt geht es einfach nicht,
property Strings[Index: Integer]: string read Get write Put; default;
function TStringList.Get(Index: Integer): string; begin if Cardinal(Index) >= Cardinal(FCount) then Error(@SListIndexError, Index); Result := FList^[Index].FString; end; außer man nimmt direkt ein dynamisches Array ohne aktivierte Indexprüfung. (siehe Compiler-Schalter oder Projektoptionen) |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Zitat:
Delphi-Quellcode:
Wo ist eigentlich dein Problem? Selbst 40.000 Datensätze sind doch in Null,Nix eingelesen über eine TStringlist eingelesen. Der Zugriff erfolgt auch schnell genug, und selbst die Suche in einer sortieren Stringlist wäre doch kein Problem, oder?
MyList.Add(MyKeyString, MyData)
Zeig uns doch mal den Code, bei dem Du Performanceprobleme bekommst. Wenn Du noch eine Nanosekunde rausholen willst, dann vergiss die TStringlist und verwende ein ARRAY OF STRING. Das vermeidet den Umweg über einen Getter-Aufruf. Aber verwende keine dynamischs Array weil das ja wieder erst umständlich und performancefressend dereferenziert werden muss :gruebel: :zwinker:
Delphi-Quellcode:
Oder geht es noch schneller?
Type
TTheMotherOfAllSchnelleStringZugriffe = ARRAY [0..39999] OF STRING; |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Hier der Code
Delphi-Quellcode:
Dieser Text dauert auf meinem langsamen Rechner ca. 17 sec. Ab markierter Stelle allein etwa 12-13 sec.
begin
Screen.Cursor := crHourGlass; startZeit := now; x:=tstringlist.Create; x.LoadFromFile('C:\DB\DatenTest.tmp'); x.Text:= StringReplace(x.Text,'ß','SSSSSSS', [rfReplaceAll]); x.Sort; x.Text:= StringReplace(x.Text,'SSSSSSS','ß',[rfReplaceAll]); x.SaveToFile('sortiert.txt'); // ab hier wird es extrem langsam a:=0; stringgrid1.RowCount:=1; //löscht überflüssige Leerzeilen for b:=0 to x.count-1 do begin progressbar6.Max:= x.Count-1 ; progressbar6.position:=b ; progressbar6.Update; if b>0 then begin if x.strings[b]=x.Strings[b-1] then begin StringGrid1.cells[1,a]:= inttostr(strtoint (StringGrid1.cells[1,a])+1) end else begin inc(a); StringGrid1.cells[1,a] := '1'; StringGrid1.cells[0,a] := x.strings[b]; StringGrid1.RowCount := StringGrid1.RowCount+1; end; end else begin StringGrid1.cells[0,a]:=x.Strings[b]; StringGrid1.cells[1,a]:='1'; end; end; x.Destroy; StopZeit := Now; StatusBar6.Panels[1].Text :='SuchZeit : '+ FormatDateTime('nn:ss:zzz', StopZeit - StartZeit) ; Screen.Cursor := crDefault; end; Der Rest der Zeit geht für das Sortieren drauf. Zitat:
Was soll denn das sein? Immer wieder fällt mir Key mit der Add funktion auf aber wozu der Key da ist habe ich keine Ahnung |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Es ist ein Wunder, dass er nur so lange braucht. Der Code ist mehr als unperformant und zudem auch sehr unsicher.
1. Zuweisen und Lesen von der Eigenschaft .Text baut den String jedesmal erneut auf bzw. parst ihn neu. 2. try/finally fehlt komplett 3. .RowCount in einer Schleife in einzelnen Schritten zu erhöhen bzw. zu verringern kostet viel Zeit. 4. Du setzt einen neuen Wert bei der Progressbar und zwingst ihn sofort neu zu zeichnen. Somit wird das Zeichnen der Progressbar mit jedem Durchlauf innerhalb der Schleife getan und kostet somit noch mehr Zeit. Grundlegend: Trenne Daten von der Oberfläche! |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Bitte wie?? was?
Zitat:
|
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
@ Muetze1 .. nein, er schrieb ja, dass es ab der Stringgrid langsam wird, das zuweisen ist alles noch fix.
also das Problem ist, dass Du den gesamten Text in die Stringgrid kopierst. Das schafft die nicht wirklich. Dafür ist sie nicht gedacht. Was Du brauchst ist eine "virtuelle" Stringgrid. Du musst im Ereignis OnDrawCell den Text mit Canvas.Textout selbst zeichnen. Und immer nur den bereich, der auf dem Bildschirm zu sehen ist. die Stringlist fungiert nur als Hintergrundspeicher. Dann gehts auch fix ... Für riesige Files, die größer sind als Dein Hauptspeicher, brauchst Du das File noch nichtmal in den Hauptspeicher laden. Dann genügt es, wenn Du nur den aktuellen Bereich, der vom User gerade angezeigt werden möchte lädst und anzeigst. Aber solche einfachen Dinge kann noch nicht mal Notepad .. Ultraedit macht das aber ... Im Prinzip reicht für solche großen Textdateien dann auch eine TDrawGrid ... P.S. für die Funktion StringReplace gibts in der JCL von Jedi eine schnellere Variante als die in der VCL |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Virtuelle Stringgrid?? langsam verstehe ich immer mehr Bahnhof.
StringReplace aus VCL --> Für das ersetzen von ca.200 ß(sz) in mehrere s sowie zurück ist die VCL doch noch schnell genug. |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Er schreibt, dass das Befüllen des StringGrid sehr langsam ist ... und das glaube ich sogar :mrgreen:
1. StringGrid1.RowCount Das ständige Erhöhen des Wertes stresst unnötig. Setze am Anfang der Schleife den Wert und fertig 2. StringGrid1.Cells[ x, y ] Benutze besser StringGrid1.Rows[ y ] und zwar so:
Delphi-Quellcode:
Denn sonst aktualisiert sich das Formular zu Tode
StringGrid1.Rows.BeginUpdate; // Anzeige der StringGrid.Reihen nicht mehr aktualisieren
for Zeile := 0 to StringGrid1.RowCount - 1 do begin Spalte := 1; // fängt bei 0 an, also ist es die 2. Spalte im StringGrid StringGrid1.Rows[ Zeile ][ Spalte ] := 'Tach auch'; end; StringGrid1.Rows.EndUpdate; // Anzeige der StringGrid.Reihen wieder aktualisieren 3. ProgressBar Die ProgressBar braucht auch nicht jede Änderung mitzubekommen
Delphi-Quellcode:
Dann sollte das schon schneller laufen
MaxWert := 10000;
ProgressBar1.Max := MaxWert; for i := 0 to MaxWert - 1 do begin if ( i mod 100 = 0 ) or ( i = MaxWert ) then ProgressBar1.Position := i; end; |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Zitat:
Es geht auch so, wie Du es gemacht hast, dann aber mit einer zweiten Scrollbar neben der Stringgrid, welche diese ersetzt. Stringgrid.rowcount wird auf 30 oder so gesetzt. virtuell bedeutet. Du hast ein File mit 1 Mio Textzeilen. Beim Anzeigen siehst Du aber nur vielleict 30 Zeilen in der Stringgrid. Die Stringgrid hat nie mehr als 30 Zeilen effektive Einträge. Beim Scrollen wird Dir nur vorgegaugelt, es wäre soviel drin. in Wahrheit wird die gewünschte Anzeige erst dann live hineingemalt. Du schmeißt also nicht 1 Mio Zeilen in die Stringgrid, sondern immer nur 30 ... |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Zitat:
.. ich hatte bei der Stringgrid gerade vergeblich BeginUpdate gesucht, .. in den Rows hat sich das also versteckt. ja .. das wäre eine Maßnahme die sehr helfen könnte :mrgreen: |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Zitat:
Die Komponente fragt diese 30 Zeilen per Index ab und ich muss nur darauf reagieren und diese Informationen liefern. Aber auch nur genau in diesem Moment. |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Zitat:
@ Sir Rufo Also zwischen beginUpdate und endUpdate den QuellText setzen und damit die Stringgrid Aktualisierung aufheben. Ich werde das ganze mal ausprobieren. |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Zitat:
.beginUpdate sowie .endUpdate wird zwar von der Codevervollständigung unterstützt, der Compiler dagegen erwartet eine eckige Klammer und compiliert deshalb nicht. Die Progressbar hab ich vorerst vollständig weggelassen so das mein Text jetzt so aussieht:
Delphi-Quellcode:
Try finally hab ich jetzt nur reingesetzt, sicher bin ich mir nicht wozu das gut sein soll.
begin
Screen.Cursor := crHourGlass; startZeit := now; x:=tstringlist.Create; x.LoadFromFile('C:\DB\DatenTest.tmp'); x.Text:= StringReplace(x.Text,'ß','SSSSSSS', [rfReplaceAll]); x.Sort; x.Text:= StringReplace(x.Text,'SSSSSSS','ß',[rfReplaceAll]); x.SaveToFile('sortiert.txt'); // ab hier wird es extrem langsam a:=0; // stringgrid1.rows.beginupdate; //fehlermeldung: [ erwartet // try for b:=0 to x.count-1 do begin if b>0 then begin if x.strings[b]=x.Strings[b-1] then begin StringGrid1.cells[1,a]:= inttostr(strtoint (StringGrid1.cells[1,a])+1) end else begin inc(a); StringGrid1.cells[1,a] := '1'; StringGrid1.cells[0,a] := x.strings[b]; StringGrid1.RowCount := StringGrid1.RowCount+1; end; end else begin StringGrid1.cells[0,a]:=x.Strings[b]; StringGrid1.cells[1,a]:='1'; end; end; // finally; // stringgrid1.rows.endUpdate //fehlermeldung: [ erwartet x.Destroy; StopZeit := Now; StatusBar6.Panels[1].Text :='SuchZeit : '+ FormatDateTime('nn:ss:zzz', StopZeit - StartZeit) ; Screen.Cursor := crDefault; end; |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Dann versuch es mal so:
Delphi-Quellcode:
begin
Screen.Cursor := crHourGlass; startZeit := now; x := tstringlist.Create; x.LoadFromFile( 'C:\DB\DatenTest.tmp' ); x.Text := StringReplace( x.Text, 'ß', 'SSSSSSS', [ rfReplaceAll ] ); x.Sort; x.Text := StringReplace( x.Text, 'SSSSSSS', 'ß', [ rfReplaceAll ] ); x.SaveToFile( 'sortiert.txt' ); // ab hier wird es extrem langsam a := 0; // StringGrid auf die maximal mögliche Zeilenanzahl setzen stringgrid1.RowCount := x.Count; for b := 0 to x.Count - 1 do begin stringgrid1.Row[ a ].BeginUpdate; try if b > 0 then begin if x.strings[ b ] = x.strings[ b - 1 ] then begin stringgrid1.cells[ 1, a ] := inttostr( strtoint( stringgrid1.cells[ 1, a ] ) + 1 ) end else begin inc( a ); stringgrid1.cells[ 1, a ] := '1'; stringgrid1.cells[ 0, a ] := x.strings[ b ]; end; end else begin stringgrid1.cells[ 0, a ] := x.strings[ b ]; stringgrid1.cells[ 1, a ] := '1'; end; finally stringgrid1.Row[ a ].EndUpdate; end; end; // Jetzt setzen wir die korrekte Anzahl der Zeilen stringgrid1.RowCount := a; x.Destroy; StopZeit := now; StatusBar6.Panels[ 1 ].Text := 'SuchZeit : ' + FormatDateTime( 'nn:ss:zzz', StopZeit - startZeit ); Screen.Cursor := crDefault; end; |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
warum zählst Du eigentlich die doppelten Einträge nicht schon vorher und schreibst erst zunm Schluß das Ergebnis in das Stringgrid?
Hab ich's überlesen oder hat bisher noch keiner darauf hingewiesen? Trenn die Daten von der Oberfläche, und ein Stringgrid ist Oberfläche. Gruß K-H |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Wenn wir schon beim Meckern sind:
Delphi-Quellcode:
x := TStringList.Create; //wobei ich die nicht unbedingt x nennen würde
try //ganz viel Code finally x.Free; //nicht Destroy end; |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Zitat:
Zitat:
Zitat:
Zitat:
|
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Zitat:
try/finally ist erledigt, mit Progreßbar von 17 sec auf 12 sec Laufzeit verringert, ohne Progressbar auf 2,5 bis 3 sec. x. Stringlist in SL. umbenannt ist erledigt, Grundlegend: Trenne Daten von der Oberfläche. --> derzeitiges Problem. Was heißt Daten von der Oberfläche trennen? Eine zweite Stringlist (zweifeldrig) für die Ergebnisse und anschließend Stringlist in Stringgrid laden?? Gruß eines total verwirrten Anfängers PS. Ihr habt mich heiß gemacht, jetzt erklärt mir worum es geht. |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Die Trennung erreicht man, wenn man sich an das EVA-Prinzip hält:
E - Eingabe V - Verarbeitung A - Ausgabe Beispiel für EVA: E - Benutzer wählt einen Dateinamen aus (z.B. in einem TEdit) V - Datei wird geöffnet und die Daten ausgelesen (z.B. in eine TStringList) V - Die Daten werden verarbeitet (Ergebnis z.B. in eine TStringList) A - Ausgabe der berechneten Daten (z.B. in ein TStringGrid) Der Quelltext deines Formulars braucht also nur noch eine Behandlung für die Eingabe (hier des Dateinames) und für die Ausgabe der Ergebnis-TStringList in TStringGrid Die Verarbeitung selber kann man in einer separaten Unit auslagern. Dadurch gewinnt man nicht nur Geschwindigkeit bei der Ausführung der Anwendung, sondern auch bei der Entwicklung, da die einzelnen Units nun nicht mehr so vollgestopft sind. Um bei diesem Beispiel zu bleiben, würde folgendes in der Verarbeitungs-Unit stehen:
Delphi-Quellcode:
In der Form wird das dann so aufgerufen:
unit uVerarbeitung;
interface function VerabeiteDatenAusDatei( const FileName : string; const Ergebnis : TStringList ) : boolean; implementation function VerabeiteDatenAusDatei( const FileName : string; const Ergebnis : TStringList ) : boolean; var sl : TStringList; begin // Erstmal ist das Ergebnis noch nicht in Ordnung Result := False; if FileExists( FileName ) then begin sl := TStringList.Create; try sl.LoadFromFile( FileName ); // Jetzt machen wir was ganz Tolles mit den Daten und schreiben das in die TStringList Ergebnis Ergebnis.Add( sl[ 0 ] ); // Ist alles korrekt durchlaufen und sind die Ergebnisse so korrekt dann Result := True; finally sl.Free; end; end; end; end.
Delphi-Quellcode:
uses uVerarbeitung;
procedure TForm1.HierPassiertEsJetzt; var MeinErgebnis : TStringList; begin MeinErgebnis := TStringList.Create; try if VerabeiteDatenAusDatei( Edit1.Text, MeinErgebnis ) then begin // Hier kommt der Quelltext für das Befüllen des StringGrids aus MeinErgebnis end; finally MeinErgebnis.Free; end; end; |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Hallo,
Das mit dem Trennen das auftrennen in ButtonClick und Funktion gemeint ist, ist mir dann heute Morgen eingefallen. Anbei mein noch ziemlich unreifer erster Versuch:
Delphi-Quellcode:
Es gibt einen Zugriffsfehler innerhalb der Funktion aber warum?
function Testfunktion(SL:TStringlist):Tstrings;
var a,b :integer; SList : TStringlist; SG: TStringgrid; begin a := 0; // StringGrid auf die maximal mögliche Zeilenanzahl setzen SG.RowCount := SList.Count; for b := 0 to SList.Count - 1 do begin SG.Rows[ a ].BeginUpdate; try if b > 0 then begin if SList.strings[ b ] = SList.strings[ b - 1 ] then begin SG.cells[ 1, a ] := inttostr( strtoint( SG.cells[ 1, a ] ) + 1 ) end else begin inc( a ); SG.cells[ 1, a ] := '1'; SG.cells[ 0, a ] := SList.strings[ b ]; end; end else begin SG.cells[ 0, a ] := SL.strings[ b ]; SG.cells[ 1, a ] := '1'; end; finally SG.Rows[ a ].EndUpdate; end; end; // Jetzt setzen wir die korrekte Anzahl der Zeilen SG.RowCount := a; Result := SG.Rows[a]; end; procedure TForm1.Button2Click(Sender: TObject); var startzeit,stopzeit:TDateTime; SL : TStringlist; begin Screen.Cursor := crHourGlass; startZeit := now; SL := TStringlist.Create; SL.LoadFromFile( 'DatenTest.tmp' ); SL.Text := StringReplace( SL.Text, 'ß', 'SSSSSSS', [ rfReplaceAll ] ); SL.Sort; SL.Text := StringReplace( SL.Text, 'SSSSSSS', 'ß', [ rfReplaceAll ] ); SL.SaveToFile( 'sortiert.txt' ); Testfunktion(SL) ; SL.Free; StopZeit := now; Label1.Caption := FormatDateTime( 'nn:ss:zzz', StopZeit - startZeit ); Screen.Cursor := crDefault; end; |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Ich weiß ja nicht was du damit erreichen willst ... ist irgendwie ohne hand und fuß
Der Zugriffsfehler kommt daher, dass du die Variable SG nicht instanziert hast.
Delphi-Quellcode:
Aber wie gesagt, das ist mehr als komisch, was du da machst.
SG := TStringGrid.Create( nil );
|
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Zitat:
Delphi-Quellcode:
weil ich Schwierigkeiten mit der Zuweisung habe. Stringgrid.cells hat String, Stringgrid.Rows dagegen TString.
SL.SaveToFile( 'sortiert.txt' );
Rückgabewert := Testfunktion(SL) ; SL.Free; Ich muß leider sagen, dies ist meine allererste Funktion und soweit wie ich weiß soll eine Funktion wiederverwendbar sein. |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Hallo Franzelchen,
wie wär es denn wenn Du uns zunächst mal sagst was Du eigentlich erreichen willst? Für mich sieht das so aus, als würdest Du irgendeine Textdatei einlesen, sortieren und in einem Stringgrid ausgeben. (Das savetofile ignorier ich jetzt) Dann markierst Du doppelte Datensätze im Stringgrid mit Zahlen >1 . Ist das soweit richtig, ist es auch das was Du erreichen willst? Edith: (Das mit Funktionen und Prozeduren lassen wir zunächst auch einmal) Gruß K-H |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Zitat:
In deiner Funktion musst du TStringGrid erzeugen (SG). Als Rückgabewert gibst du einen Teil von genau diesem SG zurück. Aber du darfst das Objekt SG in der Funktion nicht löschen, weil sonst auch der Rückgabewert verschwindet. Als Fazit bleibt, SG wird niemals freigegeben, niemals mehr benutzt und bleibt somit im Speicher bis das Programm beendet wird. Ohne die Funktion (was da überhaupt passieren soll) ist das schon mal grundverkehrt. In meinem Beispiel habe ich Dir gezeigt wie das vom Prinzip her geht. Erzeuge eine Instanz (TStringList) und übergebe der Funktion diese Instanz, auf das die Funktion dort die Ergebnisse reinschreiben kann. Somit hast du dort, wo du dann diese Daten weiterverarbeitest (zur Anzeige) auch die Kontrolle darüber, wann diese Instanz wieder aus dem Speicher entfernt werden kann (z.B. nach der Anzeige). Eine visuelle Komponente (TStringGrid) zum Berechnen zu benutzen ist schon vom Ansatz falsch, da diese Komponenten zum Anzeigen gut geeignet sind aber auch nur dafür. |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Zitat:
Deine Analyse ist völlig richtig. Mein Ziel ist es die ziemlich langsam ablaufende Prozedur (siehe Beitrag 21) möglichst zu beschleunigen. Wenn das nicht über die reine ButtonClick geht, dann vielleicht über eine Funktion (Trenne Daten von Oberfläche!). Gruß |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Zitat:
Durch dieses Ereignis kann alles passieren (z.B. eine Berechnung und die Ausgabe der Berechnung). Allerdings sollte die Berechnung ohne visuelle Komponenten auskommen. Erst bei der Ausgabe (nach der Berechnung) kommen die visuellen Komponenten ins Spiel. Dies versuchen wir dir seit einigen Beiträgen schon zu vermitteln, aber du scheinst da etwas beratungsresistent zu sein :mrgreen: |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
@ Sir Rufo
Dein letzter Beitrag hat mich überzeugt. Zitat:
Delphi-Quellcode:
Ich begreife nicht wieso Du an die Funktion eine Stringliste übergibst
function VerabeiteDatenAusDatei( const FileName : string; const Ergebnis : TStringList ) : boolean;
Delphi-Quellcode:
und diese als Ergebnis noch vorhanden ist, wenn doch der einzigste Rückgabewert der Funktion vom Typ boolean ist?
if VerabeiteDatenAusDatei( Edit1.Text, MeinErgebnis ) then
|
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
@ Sir Rufo
Dein letzter Beitrag hat mich überzeugt. Zitat:
Delphi-Quellcode:
Ich begreife nicht wieso Du an die Funktion eine Stringliste übergibst
function VerabeiteDatenAusDatei( const FileName : string; const Ergebnis : TStringList ) : boolean;
Delphi-Quellcode:
und diese als Ergebnis noch vorhanden ist, wenn doch der einzigste Rückgabewert der Funktion vom Typ boolean ist
if VerabeiteDatenAusDatei( Edit1.Text, MeinErgebnis ) then
nicht beratungsresistent eher Anfänger, sowas gibt es auch. |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Ich übergebe der Funktion eine Instanz einer TStringList - jepp
In diese TStringList legt die Funktion das Ergebnis ab. Der Rückgabewert true oder false ist nur dafür da, ob die Funktion z.B. korrekt durchgelaufen ist.
Delphi-Quellcode:
function GibMirWerteInDieListe( const Liste : TStringList ) : boolean;
begin Liste.Add( 'Dies wurde in der Funktion hinzugefügt!' ); Result := True; end;
Delphi-Quellcode:
Wenn du das ausführst, dann bekommst du eine Meldung mit 'Dies wurde in der Funktion hinzugefügt!'.
procedure IchRufeDieFunktionAuf;
var EineListe : TStringList; begin EineListe := TStringList.Create; try if GibMirWerteInDieListe( EineListe ) then ShowMessage( EineListe.Text ); finally EineListe.Free; end; end; Ich hoffe es wird jetzt klarer. |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Ok, nach der Neuinstallation meines Rechners hab ich eine Lösung:
Delphi-Quellcode:
Das Ergebnis dieser Funktion ist zB.
function VerabeiteDatenAusDatei( const FileName : string; const Ergebnis : TStringList ) : boolean;
var sL : TStringList; i,Zahl: integer; begin // Erstmal ist das Ergebnis noch nicht in Ordnung Result := False; if FileExists( FileName ) then begin sL := TStringList.Create; try sL.LoadFromFile( FileName ); // Jetzt machen wir was ganz Tolles mit den Daten und schreiben das in die TStringList Ergebnis // sL.Text:= StringReplace(sL.Text,'ß','SSSSSSS', [rfReplaceAll]); // sL.Sort; // sL.Text:= StringReplace(sL.Text,'SSSSSSS','ß',[rfReplaceAll]); // sL.SaveToFile('sortiert.txt'); Zahl := 1; for i:=0 to sL.count-1 do begin if i>0 then begin if sl.Strings[i]<>sL.Strings[i-1] then begin Zahl := 1; end; if sL.strings[i]=sL.Strings[i-1] then begin Zahl := Zahl+1; end; end; Ergebnis.Add(sl.Strings[i]+#9+IntToStr(Zahl)) ; end; // Ergebnis.Add( sl[ 0 ] ); // Ist alles korrekt durchlaufen und sind die Ergebnisse so korrekt dann Result := True; finally sL.Free; end; end; end; NameA ---> 1 NameA ---> 2 NameA ---> 3 NameB ---> 1 NameB ---> 2 usw. Ziel der Funktion NameA ---> 3 NameB ---> 2 usw. Irgendwie muß ich bei dem Vergleich if sl[i] = sl[i-1] etwas einfügen welches mehrere i einliest und zählt. Anschließend den maximalen Zahlenwert ausgibt der dann mit einem sl[i] in die Ergebnisstringliste geschrieben wird. Ich habe auch andere Funktionen und Prozeduren aus DP versucht, aber keine wirklich schnellen gefunden. Ich hoffe auf Eure weitere Unterstützung. |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Schade das hier niemand weiterhelfen kann!
|
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Was soll die Funktion denn machen? Die einzelnen Strings zählen?
Dann mach das doch:
Code:
Als Zähler verwendest Du eine TStringlist. Jedem String in der Stringlist kann ein 'Object' zugeordnet werden. Man kann nun dieses Object einfach als Zähler verwenden:
Für jede Zeile S in der StringListe:
Inc (Zähler [S]);
Delphi-Quellcode:
Wenn Du fertig mit Zählen bist, geh die Zaehlerliste durch und erzeuge deine Ergebnisliste.
i := ZaehlerListe.IndexOf(ZuZaehlenderString); // Finde Eintrag in der Zaehlerliste
If i=-1 then // Es existiert noch kein Eintrag, ZaehlerListe.AddObject(ZuZaehlenderString, TObject(1)) // erstelle also einen mit dem Wert 1 else begin n := Integer (ZaehlerListe.Objects[i]); // Ansonsten schnapp dir den Zähler und ZaehlerListe.Objects[i] := TObject(n+1); // erhöhe ihn um 1. end; [edit]Schusseligkeitsfehler korrigiert, die Hawkeye219 entdeckt hat. [/edit] |
Re: TStringlist, THashedStringlist gibts nichts schnelleres?
Hey alzaimar,
"IndexOf" und "0" => "-1", sonst passen die Kommentare nicht zu den Anweisungen ;-) Gruß Hawkeye |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:03 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