Autor Beitrag
Martin W
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 116



BeitragVerfasst: Mo 25.10.04 17:51 
Also ich hab gerade folgendes Problem...

Kurze Erklärung: Ich habe unterschiedliche Ereignisse die zu unterschiedlichen Zeiten aufgerufen werden müssen. Der Sinn der da hinter steckt ist folgender: In einem Spiel kann der User z.B. ein Gebäude bauen. Da das Gebäude Zeit braucht bis es fertig ist, brauche ich einen Timer, der mir sagt "das Gebäude x ist jetzt fertig". Und von solchen Ereignissen die zu einer Zeit x initiert werden und zu einer Zeit x gestartet werden müssen habe ich bis zu 180'000 Stück.

Geplant habe ich das ganze folgendermaßen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
type timer_execute_functions = record
                      ID_der_zu_startenden Funktion: integer;
                      Parameter_a: string;
                      Parameter_b: string;
                      Parameter_c: string;
                      Parameter_d: string;
                      Parameter_e: string;
                      Endtime: integer;
                    end;

var
  currenttimerpostion: integer = 0;
  aktionen: array of timer_execute_functions;


Ein Timer erhöht den Wert currenttimerpostion jede Sekunde um 1.


Anwendungsbeispiel:

Der User klickt auf einen Button, ab jetzt soll ein Gebäude in 500 Sekunden fertig sein. Das Array "aktionen" wird um 1 verlängert, die Werte werden ins Array geschrieben. Der Wert Endtime wird wie folgt berechnet: currenttimerpostion + 500.

Der Timer überprüft nun jede Sekunde nachdem es den Wert currenttimerpostion um 1 erhöht hat ob der Wert currenttimerpostion irgendeinem Wert Endtime entspricht. Wenn ja, wird das dazugehörige Ereigniss ausgeführt.

Allerdings funktioniert das bei 180'000 verschiedenen Records im Array nicht mehr richtig, da der PC es nicht schafft innerhalt einer Sekunde 180'000 Variablen zu überprüfen.

Wie kann ich das ganze optimieren??? Wenn ihr fragen habt, dann postet bitte!!!
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mo 25.10.04 18:59 
Vielleicht gehtst du den falschen Weg. Wenn du versuchst das ganze mit Threads zu lösen, kannst du im Thread die Variablen setzen.
Ich kann dir aber auch nicht sagen, wie ein Programm auf 180.000 Threads reagiert.
.Chef
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1112



BeitragVerfasst: Mo 25.10.04 19:24 
jasocul hat folgendes geschrieben:
Ich kann dir aber auch nicht sagen, wie ein Programm auf 180.000 Threads reagiert.

Ähm ... gar nicht? :gruebel:

_________________
Die Antworten auf die 5 häufigsten Fragen:
1. Copy(), Pos(), Length() --- 2. DoubleBuffered:=True; --- 3. Application.ProcessMessages bzw. TThread --- 4. ShellExecute() --- 5. Keine Vergleiche von Real-Typen mit "="!
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mo 25.10.04 19:54 
Hast du es ausprobiert? :twisted:
.Chef
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1112



BeitragVerfasst: Mo 25.10.04 19:57 
War ein Gedankenexperiment.

_________________
Die Antworten auf die 5 häufigsten Fragen:
1. Copy(), Pos(), Length() --- 2. DoubleBuffered:=True; --- 3. Application.ProcessMessages bzw. TThread --- 4. ShellExecute() --- 5. Keine Vergleiche von Real-Typen mit "="!
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mo 25.10.04 20:04 
War meine Ironie also nicht deutlich genug. Mist.
Nochmal:
Ob nun 180.000 Timer (im Sekundentakt) oder Threads ist mehr oder weniger egal. Es ist in beiden Fällen definitiv zuviel. Du solltest das Konzept deines Programms überdenken.
Ein Freund hat ein Programm geschrieben, dass einige Hundert Threads benutzt. Das ist dann aber auch schon eine heiße Maschine, damit das überhaupt einigermaßen läuft.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 25.10.04 20:05 
Wieso gar nicht??? Ich glaub mal eher, der Thread Manager wird, wenn er nicht grad vorher mit ner Fehlermeldung "Ungenügende Ressourcen" mit 80% Kernel-Zeiten arbeiten ;-) Für'n Spiel also genau das Richtige, um Verzögerung zu produzieren. Dann bräuchte er in jedem Thread nur ein Sleep positionieren von einer ms und kriegt gleich seine 500 Sekunden Bauzeit :evil:

Naja, würd das eher über einen Hintergrund-Thread machen, der das Array nach Ereignissen absucht und jeweils fällige Objekte an einen Event-Handler übergibt.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Mo 25.10.04 20:13 
BenBE hat folgendes geschrieben:
Naja, würd das eher über einen Hintergrund-Thread machen, der das Array nach Ereignissen absucht und jeweils fällige Objekte an einen Event-Handler übergibt.

Das wäre wohl die idealste Lösung.

_________________
Ist Zeit wirklich Geld?
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6386
Erhaltene Danke: 146

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mo 25.10.04 20:27 
Der Ansatz ist vermutlich der beste bisher. Aber ob damit auch 180.000 Objekte gut verwaltet werden können?
Schaun wir mal, was Martin dazu meint.
blackbirdXXX

ontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 1077
Erhaltene Danke: 1

Ubuntu Dapper

BeitragVerfasst: Mo 25.10.04 21:05 
Ähh.
Anderer Weg.
Ein Timer, der auf 2000ms (oder 1000ms) eingestellt ist, und 180.000 Variablen überprüft?
Dürfte etwas besser sein, als 180.000 Timer laufen zu lassen.

_________________
Klein, schwarz und ärgert Techniker? Jumper!
Martin W Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 116



BeitragVerfasst: Di 26.10.04 14:04 
blackbirdXXX hat folgendes geschrieben:
Ähh.
Anderer Weg.
Ein Timer, der auf 2000ms (oder 1000ms) eingestellt ist, und 180.000 Variablen überprüft?
Dürfte etwas besser sein, als 180.000 Timer laufen zu lassen.


Sehr gut, die Idee hatte ich auch schon ;-) Die Überschrift war nur Sinngemäß gemeint!!!

Ein Timer, der auf 2000ms (oder 1000ms) eingestellt ist, und 180.000 Variablen überprüft. Genau so habe ich mir das auch gedacht.

Ich habe im Anfangsthread das ganze genau so versucht zu erklären!!! Die Überschrift war nur Sinngemäß gemeint.

Meine Idee war so:
EINE Variable
ausblenden Delphi-Quelltext
1:
i: integer;					


EIN Record
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
type timer_execute_functions = record  
                      ID_der_zu_startenden Funktion: integer;  
                      Parameter_a: string;  
                      Parameter_b: string;  
                      Parameter_c: string;  
                      Parameter_d: string;  
                      Parameter_e: string;  
                      Endtime: integer;  
                    end;


EIN Array
ausblenden Delphi-Quelltext
1:
aktionen: array of timer_execute_functions;					


EIN Timer der jede Sekunde folgendes macht
ausblenden Delphi-Quelltext
1:
2:
inc(i);
checkfunc;


EINE Funtion, die sich in einem Thread befindet
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function checkfunc: boolean;
var
  k: integer;
begin
  for k := 0 to 179999 do
    begin
     if aktionen[k].Endtime > i then
       begin
         exe_befehl(aktion[k].ID_der_zu_startenden Funktion (..und parameter));
       end;
    end;
end;



Hat jemande einen Bessern Vorschlag???

Gruß
Martin ;-)

Ach und danke für alle eure Vorschläge bis jetzt!!!
NeWsOfTzzz
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 233


D4 Prof
BeitragVerfasst: Di 26.10.04 14:32 
Doch einen Vorschlag hätte ich... Du machst ein objekt
type
TTrigger=class
public
count;
start[1..100];
end;

das du sagen wir mal mit 600 erstellst
var
Triggers[1..600]:TTrigger;

oncreate()
for x:=1 to 600
Triggers[x]:=TTrigger.create;

trigger[1] entspricht jetzt was du in der nächsten sekunde machen willst, trigger[600] was du in 10 minuten machen willst.

Jetzt wenn Timer ausgeführt wird:
for x:=1 to Triggers[1].count do
start(Triggers[1].start[x]);

Und wenn jetzt ein start in 500 sekunden erfolgen soll dann:
inc(Triggers[500].count);
triggers[500].start[triggers[500].count]:= ...was auch immer gestartet werden soll..

und dann evtl noch jede Minute das Triggers array um 60 aufrücken lassen..
Martin W Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 116



BeitragVerfasst: Di 26.10.04 20:33 
Geht leider nicht, es kann sein, das um z.B. 16:14:18 Uhr mehrere Befehle gleichzeitig ausgeführt werden müssen...

Gibt es noch Vorschläge zur optimierung des Codes??? Auch ein "ist perfekt so" als Antwort wäre sehr nett...

Gruß
martin ;-)
NeWsOfTzzz
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 233


D4 Prof
BeitragVerfasst: Di 26.10.04 20:49 
Dann machst du halt das Trigger Objekt mit 86400 = die Anzahl Sekunden eines Tages.. Dann brauchste auch net mal "aufrücken" weil das dann sowieso den ganzen Tag abdeckt..
Und wenn du das noch für mehrere Tage brauchst dann machste das noch größer und wenn du das für noch mehr brauchst dann speicherst du halt Teile die weit in der Zukunft liegen in einer Text Datei ab
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: Di 26.10.04 20:57 
Wie wärs mit einer Liste und einsortieren? Sprich, du ordnest die Liste nach Endzeiten und sortierst neue Elemente entsprechend ihrer Endzeit ein. So weisst du das immer das oberste Item an der Reihe ist und kannst zum Beispiel in einem Thread überprüfen ob es fällig ist oder nicht.

Außerdem kann ich mir kaum vorstellen das 180.000 Elemente gleichzeitig passieren. Was macht den das Spiel alles?

Mfg, Hape!

_________________
Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
delphiDeveloper
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 48



BeitragVerfasst: Di 26.10.04 21:00 
Titel: alternative strategie
bau dir sowas wie eine warteschlange auf, jedoch sortierst du neue Elemente sofort
in der richtigen Reihenfolge ein.
On top das Ereignis was als naechstes ausgeführt werden soll.
Dann braucht ein Timer immer nur schauen ob die Zeit für dein Element on top reif ist.
NeWsOfTzzz
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 233


D4 Prof
BeitragVerfasst: Di 26.10.04 21:05 
Ja die Warteschlange hab ich mir auch schon überlegt, aber erstens müsste die Warteschlange 180.000 groß sein und bei jedem Objekt das ausgeführt wird die 179.999 nachfolgenden um einen nach vorne geschoben werden.. ergo dasselbe wie direkt alle 180.000 variablen zu prüfen..
Martin W Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 116



BeitragVerfasst: Di 26.10.04 21:12 
Titel: Re: alternative strategie
NeWsOfTzzz hat mir gerade das vorweggennommen was ich schreiben wollte ;-)

Zitat:
Außerdem kann ich mir kaum vorstellen das 180.000 Elemente gleichzeitig passieren. Was macht den das Spiel alles?


gleichzeitig ist falsch, da sind allerdings auch erst Objekte, die erst innerhalb von z.B. 10 Tagen passieren! Zum anderen - "180'000" wäre die höchstzahl der möglichen Objekte - Normalerweise arbeite ich mit einem sehr kleinen Bruchteil davon - Die Zahl 180'000 zu erreichen ist praktisch nicht möglich!!! Aber bis zu 9000 Elemente die in den Kommenden Tagen ausgeführt werden sollen ist relatistisch. Die Chache auch nur gleichzeitig auf 15'000 zu kommen ist schon sehr gering - aber mir geht es weniger um diese eine Zahl, wichtig ist nur das sie groß ist. Mir geht es darum meine Routine zu optimieren!!!

So, ich hab noch ne Frage... Wieviel Clients könnten an der INDY UDP Komponente connecten so das das Programm noch stabil läuft??? Was sagt ihr aus eigener Erfahrung dazu?
NeWsOfTzzz
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 233


D4 Prof
BeitragVerfasst: Di 26.10.04 21:16 
Soviele wie dein PC schafft? Nur geraten aber..
Martin W Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 116



BeitragVerfasst: Di 26.10.04 21:23 
NeWsOfTzzz hat folgendes geschrieben:
Soviele wie dein PC schafft? Nur geraten aber..


3 Ghz Rechenleistung, 2 TB Festplatte, 1 GB RAM, Standleitung der Telekom, Windows XP SP2!

Vorschläge?