|
![]() |
|
Registriert seit: 7. Aug 2008 Ort: Brandenburg 1.487 Beiträge Delphi 12 Athens |
#1
Der gesamte TCheckThread.execute wird vom Compiler weg optimiert, Ich habe schon einiges versucht, dazu aber keine Lösung gefunden.
Deshalb kann diese auch eigentlich nicht wegoptimiert werden. Gründe die mir einfallen: - Der gepostete Quelltext stimmt mit dem tatsächlichen nicht überein und das "override;" wurde bei der Deklaration von "Execute" vergessen. - Die Unit gehört nicht zu dem Projekt und wird deshalb nicht mehr compiliert, statt dessen wird eine alte "*.dcu" eingebunden. Unabhängig vom aktuellen Problem sind mir die Property aufgefallen. Der Zugriff auf Variablen aus mehreren Threads muss auf jeden Fall synchronisiert werden (z.B. Get- und Setmethoden mit TCriticalSection). |
![]() |
Registriert seit: 22. Mai 2013 11 Beiträge |
#2
Also wirklich helfen tut davon nichts. Ich poste mal etwas mehr Quelltext (1:1 aus Delphi kopiert):
(Im übrigen weis ich, dass sicherlich das ein oder andere etwas anders aussehen müsste oder sollte, darum kümmere Ich mich aber, wenn es vom Prinzip her erstmal läuft) Hier die procedure, die die Threads erzeugen müsste:
Delphi-Quellcode:
Hier die Unit4 mit den Threads:
procedure getbestreforgeid(reforgestringarray:treforgestringarray);
var q:integer; startstring:string; endstring:string; countarray:tcountarray; oldpoints:integer; oldresult:string; calcthread:array[0..8] of TCheckthread; threaddone:array[0..8] of boolean; threadcount:integer; btimecount:integer; label threadstartingdone; begin btimecount:=gettickcount; oldresult:='00000000000000000000000000000000'; oldpoints:=0; for q:=0 to cpucount do threaddone[q]:=true; form1.Memo2.Lines.Clear; form1.ProgressBar1.Max:=(length(reforgestringarray[0]))*(length(reforgestringarray[1]))*(length(reforgestringarray[2]))*(length(reforgestringarray[3])); form1.ProgressBar1.Position:=0; threadcount:=0; form1.label21.caption:='threads: '+inttostr(threadcount)+'/'+inttostr(cpucount); application.ProcessMessages; countarray[0]:=0; while countarray[0]<length(reforgestringarray[0]) do begin countarray[1]:=0; while countarray[1]<length(reforgestringarray[1]) do begin countarray[2]:=0; while countarray[2]<length(reforgestringarray[2]) do begin countarray[3]:=0; while countarray[3]<length(reforgestringarray[3]) do begin startstring:=''; endstring:=''; for q:=4 to 15 do countarray[q]:=0; for q:=0 to 3 do endstring:=endstring+reforgestringarray[q][countarray[q]]; for q:=4 to 15 do endstring:=endstring+reforgestringarray[q][length(reforgestringarray[q])-1]; //for q:=0 to 15 do startstring:=startstring+reforgestringarray[q][countarray[q]]; form1.Label22.Caption:=(floattostr((round((gettickcount-btimecount)/100))/10)+' seconds'); btimecount:=gettickcount; if threadcount<cpucount then begin for q:=0 to cpucount-1 do begin if threaddone[q] then begin threaddone[q]:=false; form1.memo2.lines.add('thread '+inttostr(q+1)+' of '+inttostr(cpucount)+' starting with start: '+startstring+', end: '+endstring); calcthread[q]:=tcheckthread.Create(countarray,endstring,reforgestringarray); form1.memo2.lines.add('thread started says threadhandler'); //calcthread[q].Resume; threadcount:=threadcount+1; form1.label21.caption:='threads: '+inttostr(threadcount)+'/'+inttostr(cpucount); application.ProcessMessages; Goto threadstartingdone; end; end; threadstartingdone: end; {if threadcount=cpucount then begin} {while threadcount=cpucount do begin}repeat //form1.memo2.lines.add('threadcount=cpucount2'); for q:=0 to threadcount-1 do begin //if not calcthread[q].threaddone then form1.memo2.lines.add('thread '+inttostr(q+1)+' is not done'); if calcthread[q].threaddone then begin if calcthread[q].resultpoints>oldpoints then begin oldpoints:=calcthread[q].resultpoints; oldresult:=calcthread[q].resultstring; form1.Memo2.Lines.Add('new best result: '+inttostr(oldpoints)); form1.memo2.lines.add(' str:'+oldresult); end; threadcount:=threadcount-1; form1.label21.caption:='threads: '+inttostr(threadcount)+'/'+inttostr(cpucount);; threaddone[q]:=true; calcthread[q].Free; form1.ProgressBar1.Position:=form1.ProgressBar1.Position+1; form1.Label20.Caption:=floattostr((round((form1.ProgressBar1.Position/form1.ProgressBar1.Max)*1000))/10)+' %'; form1.memo2.lines.add('thread '+inttostr(q+1)+' done'); application.ProcessMessages; end; end; sleep(500); until threadcount<>cpucount; countarray[3]:=countarray[3]+1; end; countarray[2]:=countarray[2]+1; end; countarray[1]:=countarray[1]+1; end; countarray[0]:=countarray[0]+1; end; //showmessage('ending'); while threadcount>0 do begin //form1.memo2.lines.add('threadcount=cpucount2'); for q:=0 to threadcount-1 do begin if calcthread[q].threaddone=false then form1.memo2.lines.add('thread '+inttostr(q)+' is not done'); if calcthread[q].threaddone then begin if calcthread[q].resultpoints>oldpoints then begin oldpoints:=calcthread[q].resultpoints; oldresult:=calcthread[q].resultstring; form1.Memo2.Lines.Add('new best result: '+inttostr(oldpoints)); form1.memo2.lines.add(' str:'+oldresult); end; threadcount:=threadcount-1; form1.label21.caption:='threads: '+inttostr(threadcount)+'/'+inttostr(cpucount);; threaddone[q]:=true; calcthread[q].Free; form1.ProgressBar1.Position:=form1.ProgressBar1.Position+1; form1.Label20.Caption:=floattostr((round((form1.ProgressBar1.Position/form1.ProgressBar1.Max)*1000))/10)+' %'; form1.memo2.lines.add('thread '+inttostr(q+1)+' done'); application.ProcessMessages; end; end; sleep(200); end; //showmessage('result: '+inttostr(oldpoints)+' string: '+oldresult); unit3.form3.showreforgeresult(oldresult); unit3.Form3.Visible:=true; end;
Delphi-Quellcode:
unit Unit4;
interface uses SysUtils, Classes, unit1, ExtCtrls, dialogs; //type //treforgestringarray=array[0..15] of array of string; {wowitem = record id: integer; name: string; icon: string; quality: integer; itemlvl: integer; gems: tstringlist; armor: integer; stamina: integer; intelligence: integer; strength: integer; agility: integer; hit: integer; expertise: integer; haste: integer; mastery: integer; crit:integer; dodge: integer; parry: integer; spirit: integer; end; } type TCheckThread = class(TThread) private Fstartcountarray:unit1.tcountarray; Fendstring:string; Freforgestringarray:unit1.treforgestringarray; Fthreaddone:boolean; Fresultstring:string; Fresultpoints:integer; protected function getstatname(statid:integer):string; function calcpoints(calcablestring:string):integer; procedure getbestreforgeid; procedure execute; override; public constructor Create(startcountarray:tcountarray; endstring:string; reforgestringarray:treforgestringarray); property threaddone:boolean read Fthreaddone write Fthreaddone; property resultstring:string read Fresultstring write Fresultstring; property resultpoints:integer read Fresultpoints write Fresultpoints; end; implementation constructor TCheckThread.Create(startcountarray:tcountarray; endstring:string; reforgestringarray:treforgestringarray); var i:integer; begin inherited Create(true); Fthreaddone:=false; for i:=0 to 15 do Fstartcountarray[i]:=startcountarray[i]; Fendstring:=endstring; Fresultpoints:=0; freforgestringarray:=reforgestringarray; Freeonterminate:=false; Resume; //showmessage('thread'); //self.Execute; end; function TCheckThread.getstatname(statid:integer):string; begin result:=''; if statid=1 then result:='Hit'; if statid=2 then result:='Expertise'; if statid=3 then result:='Haste'; if statid=4 then result:='Mastery'; if statid=5 then result:='Crit'; if statid=6 then result:='Dodge'; if statid=7 then result:='Parry'; if statid=8 then result:='Spirit'; end; function TCheckThread.calcpoints(calcablestring:string):integer; var calcedstats:wowitem; statvalue:integer; calcitemarray: array[0..15] of wowitem; i:integer; begin result:=0; for i:=0 to 15 do begin calcitemarray[i]:=unit1.wowitemarray[i]; statvalue:=0; if (calcablestring[2*i+1]='1')then begin statvalue:=round(calcitemarray[i].hit*0.4); calcitemarray[i].hit:=calcitemarray[i].hit-statvalue; end; if (calcablestring[2*i+1]='2')then begin statvalue:=round(calcitemarray[i].expertise*0.4); calcitemarray[i].expertise:=round(calcitemarray[i].expertise*0.6); end; if (calcablestring[2*i+1]='3')then begin statvalue:=round(calcitemarray[i].haste*0.4); calcitemarray[i].haste:=round(calcitemarray[i].haste*0.6); end; if (calcablestring[2*i+1]='4')then begin statvalue:=round(calcitemarray[i].mastery*0.4); calcitemarray[i].mastery:=round(calcitemarray[i].mastery*0.6); end; if (calcablestring[2*i+1]='5')then begin statvalue:=round(calcitemarray[i].crit*0.4); calcitemarray[i].crit:=round(calcitemarray[i].crit*0.6); end; if (calcablestring[2*i+1]='6')then begin statvalue:=round(calcitemarray[i].dodge*0.4); calcitemarray[i].dodge:=round(calcitemarray[i].dodge*0.6); end; if (calcablestring[2*i+1]='7')then begin statvalue:=round(calcitemarray[i].parry*0.4); calcitemarray[i].parry:=round(calcitemarray[i].parry*0.6); end; if (calcablestring[2*i+1]='8')then begin statvalue:=round(calcitemarray[i].spirit*0.4); calcitemarray[i].spirit:=round(calcitemarray[i].spirit*0.6); end; if (calcablestring[2*i+2]='1')then calcitemarray[i].hit:=calcitemarray[i].hit+statvalue; if (calcablestring[2*i+2]='2')then calcitemarray[i].expertise:=calcitemarray[i].expertise+statvalue; if (calcablestring[2*i+2]='3')then calcitemarray[i].haste:=calcitemarray[i].haste+statvalue; if (calcablestring[2*i+2]='4')then calcitemarray[i].mastery:=calcitemarray[i].mastery+statvalue; if (calcablestring[2*i+2]='5')then calcitemarray[i].crit:=calcitemarray[i].crit+statvalue; if (calcablestring[2*i+2]='6')then calcitemarray[i].dodge:=calcitemarray[i].dodge+statvalue; if (calcablestring[2*i+2]='7')then calcitemarray[i].parry:=calcitemarray[i].parry+statvalue; if (calcablestring[2*i+2]='8')then calcitemarray[i].spirit:=calcitemarray[i].spirit+statvalue; end; calcedstats:=extrastats; for i:=0 to 15 do begin calcedstats.hit:=calcedstats.hit+calcitemarray[i].hit; calcedstats.expertise:=calcedstats.expertise+calcitemarray[i].expertise; calcedstats.haste:=calcedstats.haste+calcitemarray[i].haste; calcedstats.mastery:=calcedstats.mastery+calcitemarray[i].mastery; calcedstats.crit:=calcedstats.crit+calcitemarray[i].crit; calcedstats.dodge:=calcedstats.dodge+calcitemarray[i].dodge; calcedstats.parry:=calcedstats.parry+calcitemarray[i].parry; calcedstats.spirit:=calcedstats.spirit+calcitemarray[i].spirit; end; if calcedstats.hit<strtoint(form1.Edit1.Text) then exit; if calcedstats.expertise<strtoint(form1.Edit2.Text) then exit; if calcedstats.haste<strtoint(form1.Edit3.Text) then exit; if calcedstats.mastery<strtoint(form1.Edit4.Text) then exit; if calcedstats.crit<strtoint(form1.Edit5.Text) then exit; if calcedstats.spirit<strtoint(form1.Edit6.Text) then exit; if calcedstats.dodge<strtoint(form1.Edit7.Text) then exit; if calcedstats.parry<strtoint(form1.Edit8.Text) then exit; if form1.ListBox1.items.IndexOf(getstatname(1))<>-1 then result:=result+calcedstats.hit*(form1.listbox1.Items.count-form1.ListBox1.Items.IndexOf(getstatname(1))); if form1.ListBox1.items.IndexOf(getstatname(2))<>-1 then result:=result+calcedstats.expertise*(form1.listbox1.Items.count-form1.ListBox1.Items.IndexOf(getstatname(2))); if form1.ListBox1.items.IndexOf(getstatname(3))<>-1 then result:=result+calcedstats.haste*(form1.listbox1.Items.count-form1.ListBox1.Items.IndexOf(getstatname(3))); if form1.ListBox1.items.IndexOf(getstatname(4))<>-1 then result:=result+calcedstats.mastery*(form1.listbox1.Items.count-form1.ListBox1.Items.IndexOf(getstatname(4))); if form1.ListBox1.items.IndexOf(getstatname(5))<>-1 then result:=result+calcedstats.crit*(form1.listbox1.Items.count-form1.ListBox1.Items.IndexOf(getstatname(5))); if form1.ListBox1.items.IndexOf(getstatname(6))<>-1 then result:=result+calcedstats.dodge*(form1.listbox1.Items.count-form1.ListBox1.Items.IndexOf(getstatname(6))); if form1.ListBox1.items.IndexOf(getstatname(7))<>-1 then result:=result+calcedstats.parry*(form1.listbox1.Items.count-form1.ListBox1.Items.IndexOf(getstatname(7))); if form1.ListBox1.items.IndexOf(getstatname(8))<>-1 then result:=result+calcedstats.spirit*(form1.listbox1.Items.count-form1.ListBox1.Items.IndexOf(getstatname(8))); //if result>28000 then showmessage(calcablestring+' result:'+inttostr(result)+' hit:'+inttostr(calcedstats.hit)+' exp:'+inttostr(calcedstats.expertise)+' haste:'+inttostr(calcedstats.haste)); end; procedure TCheckThread.getbestreforgeid; var q:integer; currentstring:string; countarray:tcountarray; points:integer; oldpoints:integer; oldresult:string; label startlabel; label endlabel; begin form1.Memo2.Lines.Add('getbestreforgeid started'); countarray:=Fstartcountarray; Goto startlabel; countarray[0]:=0; while countarray[0]<length(Freforgestringarray[0]) do begin countarray[1]:=0; while countarray[1]<length(Freforgestringarray[1]) do begin countarray[2]:=0; while countarray[2]<length(Freforgestringarray[2]) do begin countarray[3]:=0; while countarray[3]<length(Freforgestringarray[3]) do begin countarray[4]:=0; while countarray[4]<length(Freforgestringarray[4]) do begin countarray[5]:=0; while countarray[5]<length(Freforgestringarray[5]) do begin countarray[6]:=0; while countarray[6]<length(Freforgestringarray[6]) do begin countarray[7]:=0; while countarray[7]<length(Freforgestringarray[7]) do begin countarray[8]:=0; while countarray[8]<length(Freforgestringarray[8]) do begin countarray[9]:=0; while countarray[9]<length(Freforgestringarray[9]) do begin countarray[10]:=0; while countarray[10]<length(Freforgestringarray[10]) do begin countarray[11]:=0; while countarray[11]<length(Freforgestringarray[11]) do begin countarray[12]:=0; while countarray[12]<length(Freforgestringarray[12]) do begin countarray[13]:=0; while countarray[13]<length(Freforgestringarray[13]) do begin countarray[14]:=0; while countarray[14]<length(Freforgestringarray[14]) do begin countarray[15]:=0; while countarray[15]<length(Freforgestringarray[15]) do begin startlabel: currentstring:=''; for q:=0 to 15 do currentstring:=currentstring+Freforgestringarray[q][countarray[q]]; //showmessage(currentstring); //memo2.Lines.Add(currentstring); points:=calcpoints(currentstring); if points>oldpoints then begin oldpoints:=points; oldresult:=currentstring; end; if currentstring=Fendstring then Goto endlabel; form1.Memo2.Lines.Add('shortmessage'); countarray[15]:=countarray[15]+1; end; countarray[14]:=countarray[14]+1; end; countarray[13]:=countarray[13]+1; end; countarray[12]:=countarray[12]+1; end; countarray[11]:=countarray[11]+1; end; countarray[10]:=countarray[10]+1; end; countarray[9]:=countarray[9]+1; end; countarray[8]:=countarray[8]+1; end; countarray[7]:=countarray[7]+1; end; countarray[6]:=countarray[6]+1; end; countarray[5]:=countarray[5]+1; end; countarray[4]:=countarray[4]+1; end; countarray[3]:=countarray[3]+1; end; countarray[2]:=countarray[2]+1; end; countarray[1]:=countarray[1]+1; end; countarray[0]:=countarray[0]+1; end; endlabel: Fresultpoints:=oldpoints; Fresultstring:=oldresult; form1.Memo2.lines.Add('thread done says thread '+inttostr(Fresultpoints)); //showmessage('thread done says thread '+inttostr(Fresultpoints)); Fthreaddone:=true; end; procedure TCheckThread.execute; begin //Fresultpoints:=0; //showmessage('thread started '+Fendstring); getbestreforgeid; form1.Memo2.Lines.Add('thread done says thread '+inttostr(Fresultpoints)); end; end. |
![]() |
Registriert seit: 7. Aug 2008 Ort: Brandenburg 1.487 Beiträge Delphi 12 Athens |
#3
Mein Delphi warnt, compiliert aber und hält am Breakpoint in der TCheckThread.execute-Methode an.
Code:
[DCC Warnung] Unit4.pas() H2365 Schreibweise der Überschreibe-Methode TCheckThread.execute muss exakt ihrem Vorfahren TThread.Execute entsprechen
Also wirklich helfen tut davon nichts.
Die Struktur deiner Daten scheint mir für den Anwendungsfall ungeeignet. Durch geschickte Optimierung könnte man den Ablauf sicher um den Faktor 100 beschleunigen. Das ist sinnvoller als bei diesem Entwicklungsstand bereits auf Threads zu setzen. Auf jeden Fall solltest du auf "Goto" verzichten. Ein Vorschlag ohne jetzt zu viel zu verändern:
Delphi-Quellcode:
function TCheckThread.IncCountArray(var countarray: tcountarray) : Boolean;
var n: Integer; begin for n := 15 downto 0 do begin countarray[n] := countarray[n] + 1; if countarray[n] < Length(Freforgestringarray[n]) then begin Result := True; Exit; end; countarray[n] := 0; end; Result := False; end; function TCheckThread.IsCountArrayValid(const countarray: tcountarray) : Boolean; var n: Integer; begin for n := 15 downto 0 do begin if countarray[n] >= Length(Freforgestringarray[n]) then begin Result := False; Exit; end; end; Result := True; end; procedure TCheckThread.getbestreforgeid; var q:integer; currentstring:string; countarray:tcountarray; points:integer; oldpoints:integer; oldresult:string; begin oldpoints := 0; oldresult := '00000000000000000000000000000000'; countarray := Fstartcountarray; if IsCountArrayValid(countarray) then begin repeat currentstring:=''; for q := 0 to 15 do currentstring := currentstring + Freforgestringarray[q][countarray[q]]; //showmessage(currentstring); //memo2.Lines.Add(currentstring); points := calcpoints(currentstring); if oldpoints < points then begin oldpoints := points; oldresult := currentstring; end; if currentstring=Fendstring then Break; //form1.Memo2.Lines.Add('shortmessage'); until not IncCountArray(countarray); end; //form1.Memo2.lines.Add('thread done says thread '+inttostr(Fresultpoints)); //showmessage('thread done says thread '+inttostr(Fresultpoints)); resultpoints := oldpoints; resultstring := oldresult; end; procedure TCheckThread.Execute; begin //Fresultpoints:=0; //showmessage('thread started '+Fendstring); getbestreforgeid; threaddone:=true; //form1.Memo2.Lines.Add('thread done says thread '+inttostr(Fresultpoints)); end; |
![]() |
Registriert seit: 22. Mai 2013 11 Beiträge |
#4
Mein Delphi warnt, compiliert aber und hält am Breakpoint in der TCheckThread.execute-Methode an.
Code:
[DCC Warnung] Unit4.pas() H2365 Schreibweise der Überschreibe-Methode TCheckThread.execute muss exakt ihrem Vorfahren TThread.Execute entsprechen
Also wirklich helfen tut davon nichts.
Die Struktur deiner Daten scheint mir für den Anwendungsfall ungeeignet.
Durch geschickte Optimierung könnte man den Ablauf sicher um den Faktor 100 beschleunigen. Das ist sinnvoller als bei diesem Entwicklungsstand bereits auf Threads zu setzen. Auf jeden Fall solltest du auf "Goto" verzichten. Ein Vorschlag ohne jetzt zu viel zu verändern: (...) ![]() ![]() Geändert von Murkas (25. Mai 2013 um 14:09 Uhr) |
![]() |
Registriert seit: 22. Mai 2013 11 Beiträge |
#5
Also..
Ich habe jetzt die Unit nochmal komplett aus dem Projekt gehauen und von Delphi ein neues Thread-Objekt erzeugen lassen, dem ich meine Prozeduren wieder hinzugefügt habe. Nur leider hat es nicht geholfen. Ich habe auch probiert mal keine eigene TCheckThread.Create Prozedur zu benutzen, sondern die von TThread. Alles kein Erfolg. Mir gehen so langsam die Ideen aus. Hat keiner mehr eine Idee? |
![]() |
Registriert seit: 15. Feb 2008 Ort: Baden-Württemberg 2.332 Beiträge Delphi 2007 Professional |
#6
Also dein Sourcecode ist noch sehr suboptimal.
Ich weiss nich ob es dir aufgefallen ist, aber dein Code besteht aus permanenten Wiederholungen. Das Ganze wird sehr unübersichtlich und da nicht mal Kommentare vorhanden sind versteht man eigentlich nur "Bahnhof". Guter Code soll aber selbsterklärend und ohne Wiederholungen sein. Hier ein kleines Beispiel:
Delphi-Quellcode:
Warum reitest du ständig auf calcitemarray[i]
herum?
function TCheckThread.calcpoints(calcablestring:string):integer;
var calcedstats:wowitem; statvalue:integer; calcitemarray: array[0..15] of wowitem; i:integer; begin result:=0; for i:=0 to 15 do begin calcitemarray[i]{*}:=unit1.wowitemarray[i]; statvalue:=0; if (calcablestring[2*i+1]='1')then begin statvalue:=round(calcitemarray[i]{*}.hit*0.4); calcitemarray[i]{*}.hit:=calcitemarray[i]{*}.hit-statvalue; end; Verwendet eine einfache lokale Variable var item:wowitem; und die Sache wird schon klarer. Du verwendest 16 Mal den Ausdruck calcablestring[2*i+1] ; das tut doch in den Augen weh. Auch hier: verwende eine lokale Zwischenvariable (Datentyp char)! Deine Funktion/Methoden sind elendlang; sie passen nicht auf eine Seite und man muss ständig hoch und runterscrollen. Halte deine Funktionen kurz und verwende Unterfunktionen! Wenn du diese beiden Regeln beachtest kannst du deinen Code deutlich verbessern.
fork me on
![]() |
![]() |
Registriert seit: 22. Mai 2013 11 Beiträge |
#7
Also ich finde es ja sehr hilfreich, dass ihr versucht mir zu helfen, meinen Code zu verbessern, aber ich würde gerne erst einmal Alles zum laufen zu bringen, bevor ich zu optimieren beginne. Würde es euch denn helfen mein aktuelles Problem zu lösen, wenn ich meinen Code auskommentiere etc.?
|
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |