habe ich nun im Code erklärtDragon hat geschrieben:wieso rechnest du bei der stringliste in der schleife -3.
und kann man da überhaupt mit einer stringliste arbeiten ich meine muss dann jedes wort nicht in einer extra zeil vorliegen?
performanceproblem while schleife
-
- Beiträge: 298
- Registriert: Di 23. Nov 2010, 23:41
- OS, Lazarus, FPC: Ubuntu/Win, Lazarus trunk, FPC trunk
- CPU-Target: 32Bit/64Bit
- Wohnort: Geldern
- Kontaktdaten:
Re: performanceproblem while schleife
MfG Gocher
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me
-
- Beiträge: 162
- Registriert: Mi 31. Jul 2013, 15:07
- OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80
Re: performanceproblem while schleife
hab mich mal eben selbst qequotet weil ich übersehen hab das es schon eine dritte seite gab^^Edit1:
- Danke für die erweiterten kommentare
habs so mal probiert das programm crasht dann aber mit "EStringListError: List index (416) out of bounds"
Edit1:
Habe nochmal komplett sauber rekompiliert der fehler tritt nun nicht mehr auf
Edit2:
habs mal mit einer größeren datei probiert 11470Wörter(78kB) die ist unparsbar
dann nehme ich einfach kleinere dateien
Danke für eure hilfe
-
- Beiträge: 298
- Registriert: Di 23. Nov 2010, 23:41
- OS, Lazarus, FPC: Ubuntu/Win, Lazarus trunk, FPC trunk
- CPU-Target: 32Bit/64Bit
- Wohnort: Geldern
- Kontaktdaten:
Re: performanceproblem while schleife
TStringList ist meines Wissens auf 134.217.728 Strings begrenzt (MaxListSize)
MfG Gocher
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me
-
- Beiträge: 162
- Registriert: Mi 31. Jul 2013, 15:07
- OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80
Re: performanceproblem while schleife
Und wie siehts mit der max größe von einem array aus
edit: das problem ist jetzt nur noch, wenn ich ein zweites file lade, überschreibt es das erste, hab zweimal das selbe file geladen, ergo müsste sich die anzahl bei allen verdoppeln, tut sie aber nicht die anzahl bleibt gleich
edit: das problem ist jetzt nur noch, wenn ich ein zweites file lade, überschreibt es das erste, hab zweimal das selbe file geladen, ergo müsste sich die anzahl bei allen verdoppeln, tut sie aber nicht die anzahl bleibt gleich
-
- Beiträge: 298
- Registriert: Di 23. Nov 2010, 23:41
- OS, Lazarus, FPC: Ubuntu/Win, Lazarus trunk, FPC trunk
- CPU-Target: 32Bit/64Bit
- Wohnort: Geldern
- Kontaktdaten:
Re: performanceproblem while schleife
Wie sehen eigentlich deine Variablen-Deklarationen aus?
An welcher Stelle lädst Du die Datei, wie sieht dein kompletter Code aus?
An welcher Stelle lädst Du die Datei, wie sieht dein kompletter Code aus?
Zuletzt geändert von gocher am So 15. Mai 2016, 16:40, insgesamt 1-mal geändert.
MfG Gocher
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me
-
- Beiträge: 162
- Registriert: Mi 31. Jul 2013, 15:07
- OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80
Re: performanceproblem while schleife
zurzeit noch so
muss nr noch den alten kram rauswerfen wenn alles klappt wie es soll
Das wäre das record
Code: Alles auswählen
var
database: array of Statistiken;
content: string;
s: string;
//Analyse der Textlänge
Text: string;
Anzahl: longint;
sanzahl: string;
//Allgemeine schleifenzähler
i: integer;
i2: integer;
//DAtenbank befüllung
Prozent: single;
sProzent: string;
step: single;
found: boolean;
// w : byte;
//wort : array[1..3] of string;
sl: TStringList;
//wort1, wort2, folgewort: string;
start, T1, T2, t3: word;
begin
Das wäre das record
Code: Alles auswählen
type
Statistiken = record
Wort1: string;
Wort2: string;
Folgewort: string;
Anzahl: word;
Vorkommen: byte;
end;
-
- Beiträge: 162
- Registriert: Mi 31. Jul 2013, 15:07
- OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80
Re: performanceproblem while schleife
Es ist teil einer .so das wäre hier die kompklette procedure
Code: Alles auswählen
procedure MessageProc(AUser: PChar; AChannel: PChar; AMessage: PChar);
var
database: array of Statistiken;
content: string;
s: string;
//Analyse der Textlänge
Text: string;
Anzahl: longint;
sanzahl: string;
//Allgemeine schleifenzähler
i: integer;
i2: integer;
//DAtenbank befüllung
Prozent: single;
sProzent: string;
step: single;
found: boolean;
// w : byte;
//wort : array[1..3] of string;
sl: TStringList;
//wort1, wort2, folgewort: string;
start, T1, T2, t3: word;
begin
Content := AMessage;
//Datenbankgeneriereung
if AnsiStartsText('!markov add ', Content) then
begin
s := Copy(Content, 13, length(Content));
//Lade text und zähle wörter
Text := Loadfile('./markovtexte/' + s);
Anzahl := Wordcount(Text);
writeln(anzahl);
sanzahl := IntToStr(Anzahl);
irc.say(Achannel, PChar('Woerter im zu einlesendem text ' + sAnzahl));
i := 1;
sl := TStringList.Create;
sl.Delimiter := ' '; // Leerzeichen als Wort Trenner
sl.QuoteChar := #$0; // keine " als Maskierung
sl.DelimitedText := Text; // durch diese Zuordnung wird der Zugewiesene Text in einzelne Strings
// (Worte in diesem Fall unterteilt)
// dann kannst du dir alles ausschneiden ersparen
for i := 0 to sl.Count - 3 do
// die Schleife beginnt bei 0 (erstes Wort) und aus den letzten zwei Worten kannst Du keine
// dreierkombinationen machen das würde zu Zugriffsverletzungen führen
begin
found := False;
if length(Database) > 0 then
begin
for i2 := 0 to length(Database) - 1 do
begin
if (Database[i2].Wort1 = sl.strings[i]) and (Database[i2].Wort2 = sl.strings[i + 1]) and (Database[i2].Folgewort = sl.strings[i + 2]) then
begin
Inc(Database[i2].Anzahl);
found := True;
break;
end;
end;
end;
if not found then
begin
t2 := length(Database);
Setlength(Database, t2 + 1);
Database[t2].Wort1 := sl.strings[i];
Database[t2].Wort2 := sl.strings[i + 1];
Database[t2].Folgewort := sl.strings[i + 2];
Database[t2].Anzahl := 1;
end;
end;
sl.Free;
Writeln(database[1].wort1 + database[1].wort2 + database[1].folgewort); writeln(Database[1].anzahl);
Writeln(database[2].wort1 + database[2].wort2 + database[2].folgewort); writeln(Database[2].anzahl);
Writeln(database[3].wort1 + database[3].wort2 + database[3].folgewort); writeln(Database[3].anzahl);
Writeln(database[4].wort1 + database[4].wort2 + database[4].folgewort); writeln(Database[4].anzahl);
//Baue satzvergleichsdatenbank auf
//Berechne wahrscheinlichkeiten
end;
Zuletzt geändert von Dragon am So 15. Mai 2016, 17:09, insgesamt 1-mal geändert.
-
- Beiträge: 298
- Registriert: Di 23. Nov 2010, 23:41
- OS, Lazarus, FPC: Ubuntu/Win, Lazarus trunk, FPC trunk
- CPU-Target: 32Bit/64Bit
- Wohnort: Geldern
- Kontaktdaten:
Re: performanceproblem while schleife
Code: Alles auswählen
var
// start, T1, T2 : word; // word 0 .. 65535
T2: Cardinal;
Byte 0 .. 255
Shortint -128 .. 127
Smallint -32768 .. 32767
Word 0 .. 65535
Integer either smallint or longint
Cardinal longword
Longint -2147483648 .. 2147483647
Longword 0 .. 4294967295
Int64 -9223372036854775808 .. 9223372036854775807
QWord 0 .. 18446744073709551615
Ich kenne Deine Datei nicht wenn Du nur die Worte brauchts musst du sowieso vorher ".", ",", "!", ";", ... durch Leerzeichen ersetzen und doppelte Leerzeichen zusammenführen. Da könntest Du dann eventuell noch andere Anpassungen vornehem.
!!! Wenn die Funktion mehrfach aufgerufen werden soll und das Array (Datenbank) sich immer erweitern soll, sollte natürlich das Array keine lokale Variable sein!
Int64 verschenkt ein Bit, negative Wortanzahlen gibt es nicht


18.446.744.073.709.551.615 = 18 Trillionen 446 Billiarden 744 Billionen 73 Milliarden 709 Millionen 551 Tausend 615
lass Dir das mal auf der Zunge zergehen

!!! T2 ist immer noch etwas klein für die Bibel!
Beachte die !!! , ich muss mich nun ausklinken mein Hund sieht mich so verliebt an ich glaube er muss Gassi.
Hat Spass gemacht!
Zuletzt geändert von gocher am So 15. Mai 2016, 17:23, insgesamt 9-mal geändert.
MfG Gocher
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me
-
- Beiträge: 162
- Registriert: Mi 31. Jul 2013, 15:07
- OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80
Re: performanceproblem while schleife
ok ,danke parsbar ist die datei aber immernoch nicht.
entweder liegt es daran das die datei nichtasciizeichen enthält oder sie ist selbst für cardinal zu lang
Edit:
entweder liegt es daran das die datei nichtasciizeichen enthält oder sie ist selbst für cardinal zu lang
Edit:
- Hab das Bottleneck gefunden, die Wordcountfunktion am Anfang war das Poblem und hab jetzt einen int64 genommen.
Testfile 2 lässt sich nun ebenfalls parsen
danke
- Wenn der die satzzeichen an den worten berhält ist das sogar glaube besser
- gibs eig eine möglichkeit ein integer mit unbegrenzter größe zu haben, die strings sind ja auch meine ich unendlich groß.
Was ist die max größe von einem array of record bzw einem (dyn)array
- Hab mal aus meinem einen Vorheriegen Post, den ganzen alten Code rausgeworfen der übersichtkeithalber
- Meinetesttextdateien waren
https://de.wikipedia.org/wiki/Go_%28Spiel%29 das ist die große datei
http://www.heise.de/developer/meldung/G ... 07846.html das die kleine
übr gabs keinen speziellen grund auser die länge wieso ich gerade diese texte genommen habe(ich habe keinerlei rechte u/o copyrigth an den verwendeten testdateien)
- nein ich parse nicht die bibel^^
- Viel spaß beim gassi gehen und danke für deine ganze hilfe
-
- Beiträge: 162
- Registriert: Mi 31. Jul 2013, 15:07
- OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80
Re: performanceproblem while schleife
Ich grabe diesen Thread nochmal aus weil ich an gochers Code nochmal Veränderungen vorgenommen habe. Dies habe ich gemacht weil mir ein wesentlich besserer weg eingefallen ist, um die menge der Informationen besser zu speichern um die Verarbeitung und Analyse zu vereinfachen.
Dazu lege ich jetzt nicht mehr nur ein Doppelpaar an + das entsprechende Folgewort, sondern nur noch einmal ein Doppelwortpaar und das Folgewort als Array sowie Anzahl & vorkommen, um somit Redundanzen der Doppelpaare zu sparen. doch irg funktioniert da noch nicht richtig und ich hab keineIdee wie ich das fixen könnte
Und noch eine unabhängige frage ich habe gehört das packed records kleiner sind wieso ist dies der Fall wird der Inhalt dann komprimiert?
edit: habs denke gelöst
Dazu lege ich jetzt nicht mehr nur ein Doppelpaar an + das entsprechende Folgewort, sondern nur noch einmal ein Doppelwortpaar und das Folgewort als Array sowie Anzahl & vorkommen, um somit Redundanzen der Doppelpaare zu sparen. doch irg funktioniert da noch nicht richtig und ich hab keineIdee wie ich das fixen könnte
Und noch eine unabhängige frage ich habe gehört das packed records kleiner sind wieso ist dies der Fall wird der Inhalt dann komprimiert?
Code: Alles auswählen
type
Statistiken = record
Wort1: string;
Wort2: string;
Folgewort: array of string;
Anzahl: array of integer;
Vorkommen: array of byte;
end;
var
database: array of Statistiken;
Code: Alles auswählen
procedure MessageProc(AUser: PChar; AChannel: PChar; AMessage: PChar);
var
// database: array of Statistiken;
content: string;
s: string;
//Analyse der Textlänge
Text: string;
//Allgemeine schleifenzähler
i: integer;
i2: integer;
i3: integer;
found: boolean;
sl: TStringList;
t2 : qword;
begin
Content := AMessage;
//Datenbankgeneriereung
if AnsiStartsText('!markov add ', Content) then
begin
s := Copy(Content, 13, length(Content));
//Lade text und zähle wörter
Text := Loadfile('./markovtexte/' + s);
{Anzahl := Wordcount(Text);
writeln(anzahl);
sanzahl := IntToStr(Anzahl);
irc.say(Achannel, PChar('Woerter im zu einlesendem text ' + sAnzahl));}
i := 1;
sl := TStringList.Create;
sl.Delimiter := ' '; // Leerzeichen als Wort Trenner
sl.QuoteChar := #$0; // keine " als Maskierung
sl.DelimitedText := Text; // durch diese Zuordnung wird der Zugewiesene Text in einzelne Strings
// (Worte in diesem Fall unterteilt)
// dann kannst du dir alles ausschneiden ersparen
for i := 0 to sl.Count - 3 do
// die Schleife beginnt bei 0 (erstes Wort) und aus den letzten zwei Worten kannst Du keine
// dreierkombinationen machen das würde zu Zugriffsverletzungen führen
begin
found := False;
if length(Database) > 0 then
begin
//Überprüft nach vorhandensein von doppelpaaren
for i2 := 0 to length(Database) - 1 do
begin
if (Database[i2].Wort1 = sl.strings[i]) and (Database[i2].Wort2 = sl.strings[i + 1]) then
begin
//innerhalb der wortgruppe nach übereinstimmung suchen
for i3 := 0 to length(Database[i2].Folgewort)-1do
begin
if Database[i2].Folgewort[i3] = sl.strings[i + 2] then
begin
Inc(Database[i2].Anzahl[i3]);
found := True;
break;
end
else
begin
//ohne übereinstimmung neuen untereintrag in wortpaar anlegen
t2 := length(Database[i2].Folgewort);
Setlength(Database[i2].Folgewort, t2 + 1);
Setlength(Database[i2].Anzahl, t2 + 1);
Database[i2].Folgewort[i3] := sl.strings[i + 2];
Database[i2].Anzahl[i3] := 1;
found := true;
break;
end;
end;
end;
end;
end;
if not found then
begin
//ohne worthauptgruppe neue wortpaarhauptgruppe anlegen
t2 := length(Database);
Setlength(Database, t2 + 1);
Setlength(Database[i2].Folgewort, length(Database[i2].Folgewort)+ 1);
Setlength(Database[i2].Anzahl, length(Database[i2].Folgewort)+ 1);
Database[t2].Wort1 := sl.strings[i];
Database[t2].Wort2 := sl.strings[i + 1];
Database[t2].Folgewort[1] := sl.strings[i + 2];
Database[t2].Anzahl[1] := 1;
end;
end;
sl.Free;
//Debugoutput
Writeln(database[0].wort1 + database[0].wort2 + database[0].folgewort[0]); writeln(Database[0].anzahl[0]);
Writeln(database[0].wort1 + database[0].wort2 + database[0].folgewort[1]); writeln(Database[0].anzahl[1]);
Writeln(database[0].wort1 + database[0].wort2 + database[0].folgewort[2]); writeln(Database[0].anzahl[2]);
//Baue satzvergleichsdatenbank auf
//Berechne wahrscheinlichkeiten
end