performanceproblem while schleife

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Dragon
Beiträge: 162
Registriert: Mi 31. Jul 2013, 15:07
OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80

performanceproblem while schleife

Beitrag von Dragon »

Hallo liebe community, ich habe ein Problem mit einer whileschleife, nämlich das sie ultra langsam ist.

//anzahl ist die anzahl der wörter im zu parsendem string

Code: Alles auswählen

while i < anzahl-1 do
     begin
        Prozent := step * i;
        sprozent := floattostr(roundto(prozent, -2));
        writeln('[1 von 3 trage woerter in datenabank ein] ' + sProzent + '%');
        //trägt einen neuen eintrag in die datenbank ein
 
        t1 := PosEx(' ', text , start);
        wort1 := copy(text, start, t1-start);
        t2 := PosEx(' ', text , t1+1);
        wort2 := copy(text, t1, t2-t1);
        t3 := PosEx(' ', text, t2+1);
        folgewort := copy(text, t2, t3-t2);
        start := t1+1;
        t1 := t2+1;
        t2 := t3+1;
 
        for i2 := 1 to length(database) do
        begin
          if Database[i2].Wort1 = wort1 then
          begin
            if Database[i2].wort2 = wort2 then
            begin
              if Database[i2].folgewort = folgewort then
              begin
                database[i2].Anzahl := database[i2].Anzahl + 1;
              end;
            end;
          end
          else
          begin
            Setlength(database, length(database) + 1);
            database[i2+1].wort1 := wort1;
            database[i2+1].wort2 := wort2;
            database[i2+1].folgewort := folgewort;
            database[i2+1].anzahl := 1;
          end;
        end;
        Inc(i);
      end;


ich hab ein Test mit einer Textdatei mit 416 Wörtern gemacht, nach 30min waren gerade erstmal ~10% laut anzeige geparsed, wo liegt hier das bottleneck vor

Euklid
Lazarusforum e. V.
Beiträge: 2829
Registriert: Fr 22. Sep 2006, 10:38
OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
Wohnort: Hessen
Kontaktdaten:

Re: performanceproblem while schleife

Beitrag von Euklid »

Wie groß ist denn die Länge der Database vor dem ersten Durchlauf?

Dragon
Beiträge: 162
Registriert: Mi 31. Jul 2013, 15:07
OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80

Re: performanceproblem while schleife

Beitrag von Dragon »

es ist ein array of record und komplett leer zu anfang

Euklid
Lazarusforum e. V.
Beiträge: 2829
Registriert: Fr 22. Sep 2006, 10:38
OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
Wohnort: Hessen
Kontaktdaten:

Re: performanceproblem while schleife

Beitrag von Euklid »

Dragon hat geschrieben:es ist ein array of record und komplett leer zu anfang


... dann hätte es die Length 0 und die for-Schleife würde garnicht durchlaufen werden. Sehe ich das richtig?

Ich sehe in dem Code, den Du gepostet hast keinen Fehler. Ich vermute, dass die ein- oder andere Variable nicht initialisiert wurde und zu Beginn einen zufälligen, großen Wert besitzt und die Schleifen entsprechend viel Zeit benötigen. D.h. vermutlich steckt der Fehler im Code oberhalb der While-Schleife.

Dragon
Beiträge: 162
Registriert: Mi 31. Jul 2013, 15:07
OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80

Re: performanceproblem while schleife

Beitrag von Dragon »

Der code oberhalb incl schleife sieht so aus

Code: Alles auswählen

 
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));
 
      //eintragen der wörter in die datenbank
      step := 100 / (anzahl-1);
      start := 1;
      if length(database) < 1 then
      begin
        setlength(database, 1);
      end;
      i := 1;
      while i < anzahl-1 do
     begin
        Prozent := step * i;
        sprozent := floattostr(roundto(prozent, -2));
        writeln('[1 von 3 trage woerter in datenabank ein] ' + sProzent + '%');
        //trägt einen neuen eintrag in die datenbank ein
 
        t1 := PosEx(' ', text , start);
        wort1 := copy(text, start, t1-start);
        t2 := PosEx(' ', text , t1+1);
        wort2 := copy(text, t1, t2-t1);
        t3 := PosEx(' ', text, t2+1);
        folgewort := copy(text, t2, t3-t2);
        start := t1+1;
        t1 := t2+1;
        t2 := t3+1;
 
        for i2 := 1 to length(database) do
        begin
          if Database[i2].Wort1 = wort1 then
          begin
            if Database[i2].wort2 = wort2 then
            begin
              if Database[i2].folgewort = folgewort then
              begin
                database[i2].Anzahl := database[i2].Anzahl + 1;
              end;
            end;
          end
          else
          begin
            Setlength(database, length(database) + 1);
            database[i2+1].wort1 := wort1;
            database[i2+1].wort2 := wort2;
            database[i2+1].folgewort := folgewort;
            database[i2+1].anzahl := 1;
          end;
        end;
        Inc(i);
      end;   

Euklid
Lazarusforum e. V.
Beiträge: 2829
Registriert: Fr 22. Sep 2006, 10:38
OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
Wohnort: Hessen
Kontaktdaten:

Re: performanceproblem while schleife

Beitrag von Euklid »

Sieht eigentlich alles korrekt aus. Allerdings hat er maximal 450*450 Schleifendurchläufe, das müsste in wenigen hundertstel Sekunden erledigt sein.

Das Einzige, was mir noch einfällt und was Du mal probieren könntest, ist statt

Code: Alles auswählen

 
      if length(database) < 1 then
      begin
        setlength(database, 1);
      end


nur

Code: Alles auswählen

setlength(database, 1);


zu schreiben.

Dragon
Beiträge: 162
Registriert: Mi 31. Jul 2013, 15:07
OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80

Re: performanceproblem while schleife

Beitrag von Dragon »

nein läuft leider immernoch so langsam :(

Euklid
Lazarusforum e. V.
Beiträge: 2829
Registriert: Fr 22. Sep 2006, 10:38
OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
Wohnort: Hessen
Kontaktdaten:

Re: performanceproblem while schleife

Beitrag von Euklid »

Dragon hat geschrieben:nein läuft leider immernoch so langsam :(


Okay, hoffentlich kommt ein anderer Forennutzer auf bessere Ideen als ich ;)

Wie gesagt, sollte eine Schleife mit 450*450 Durchläufen in Null komma nix durch sein.

Wenn Du nicht so lange warten kannst, würde ich nach und nach einzelne Abschnitte in der While-Schleife auskommentieren. Wenns dann schneller läuft, ist der Flaschenhals entdeckt^^

Viel Erfolg! :D

Dragon
Beiträge: 162
Registriert: Mi 31. Jul 2013, 15:07
OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80

Re: performanceproblem while schleife

Beitrag von Dragon »

trotzdem danke für deine hilfe euklid

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 4284
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: performanceproblem while schleife

Beitrag von af0815 »

Such mal nach Lazarus und Profiling.

Hast du bei den Compileroptionen die Überprüfungen drinnen (Rangecheck etc.), die können die Ausführung bremsen sind aber ein Sicherheitsnetz beim Coden.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Dragon
Beiträge: 162
Registriert: Mi 31. Jul 2013, 15:07
OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80

Re: performanceproblem while schleife

Beitrag von Dragon »

Ich habs mit den standart einstellungen probiert und einmal mit opt level 4 + smart linking jeweils einmal mit und ohne debuggerinformationen.

gocher
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

Beitrag von gocher »

ich vermute mal Du willst was ganz anderes als was Du machst!

Code: Alles auswählen

 
found := false;
for i2 := 1 to length(database) do
begin
  if (Database[i2].Wort1 = wort1) and (Database[i2].wort2 = wort2) and (Database[i2].folgewort = folgewort) then
  begin
    inc(database[i2].Anzahl);
    found := true;
    break;
  end;
end;
if not found then
begin
  Setlength(database, length(database) + 1);
  database[i2+1].wort1 := wort1;
  database[i2+1].wort2 := wort2;
  database[i2+1].folgewort := folgewort;
  database[i2+1].anzahl := 1;
end;
MfG Gocher
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me

Dragon
Beiträge: 162
Registriert: Mi 31. Jul 2013, 15:07
OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80

Re: performanceproblem while schleife

Beitrag von Dragon »

Was ich vorhabe ist ein text zu parsen und immer die wörter rauszunehmen also zumbeispiel:

Das ist ein test ob der parser den text richtig ...

Das ist ein
ist ein test
ein test ob
test ob der
ob der parser
....

und wenn so ein dreierblock mehr als einmal vorkommt soll die anzahl um eins erhöht werden anstatt das ein neuer eintrag angelegt wird

gocher
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

Beitrag von gocher »

sage ich ja, das machst du aber nicht!
Einfach Deine Routine mit 20 Zeilen testen und das Ergebnis kontrollieren, dann wirst du dich Wundern das Dein Ergebnis wesentlich länger als 20 Zeilen ist.
Denn für jedes nicht übereinstimmende Erste Wort in der Ergebnisliste hängst du eine neue Zeile an, das ist so etwas wie ein Reiskorn aufs erste Feld des Schachbretts und dann immer verdoppeln.

Ach so ja, mein Beispiel sollte genau so funktionieren wie Du es eigentlich gedacht hattest.
MfG Gocher
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me

Dragon
Beiträge: 162
Registriert: Mi 31. Jul 2013, 15:07
OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80

Re: performanceproblem while schleife

Beitrag von Dragon »

ok danke gocher,
habs mal mit deinem code probiert, die Schleife macht 3 durchläufe danach gibs keinnen konsolenoutput mehr, also denke ich das die sich irg festfährt

Antworten