Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Problem beim erzeugen von Zufallszahlen 100.000< (https://www.delphipraxis.net/48531-problem-beim-erzeugen-von-zufallszahlen-100-000-a.html)

Hallo_Thomas 26. Jun 2005 23:51


Problem beim erzeugen von Zufallszahlen 100.000<
 
Liste der Anhänge anzeigen (Anzahl: 1)
Und zwar habe ich folgenes Problem, wenn bei diesen Befehl unten versuche 100.000 Zufallszahlen zu erzeugen, schaffe ich eine Rechnerauslastung von 99% und Speicherauslastung steigt, und die Zahlen werden erst nach ca. 2min dargestellt.
Während bei 10.000 Zahlen der Vorgang gerade mal 1,2s dauert!

Wie kann ich diesen Vorgang beschleunigen?






Delphi-Quellcode:
procedure TForm1.SpeedButton8Click(Sender: TObject);
Var Zahl,i   :Integer;
    farbe  :TColor;
begin
  randomize;
  for i:=1 to StrToInt64(Edit1.Text) do//////hier wird bestimmt wieviel Zz erzeugt werden
  begin
    Zahl :=random(7)+1;
    meineListe.Insert(0,IntToStr(Zahl));
    if Zahl in [1,37] then farbe := clblue else
    farbe := clyellow;
    Listbox1.Items.InsertObject(0,IntToStr(Zahl), Pointer(farbe));
  end;
end;

Nothine 27. Jun 2005 00:35

Re: Problem beim erzeugen von Zufallszahlen 100.000<
 
Es ist sehr gut möglich das die reine Erzeugung der Zufallszahlen gar nicht mal so lange dauert, sondern vielmehr die Ausgabe in der ListBox. Ich würd zu diesem Zweck die ganze for-Schleife einfach mal in einen Delphi-Referenz durchsuchenBeginUpdate/Delphi-Referenz durchsuchenEndUpdate-Block einschließen. (selbiges gilt möglicherweise auch für "meineListe", je nachdem ob sie sichtbar ist)

edit: ach ja und nur der form halber, Randomize sollte man in aller Regel nur einmal beim Programmstart aufrufen (initialization oder OnFormCreate).

xaromz 27. Jun 2005 00:36

Re: Problem beim erzeugen von Zufallszahlen 100.000<
 
Hallo,

zum Beschleunigen fallen mir da zwei Sachen ein:

Delphi-Quellcode:
ListBox1.Items.BeginUpdate; // <--
for i:=1 to StrToInt64(Edit1.Text) do//////hier wird bestimmt wieviel Zz erzeugt werden
begin
  Zahl :=random(7)+1;
  meineListe.Add(IntToStr(Zahl)); // <--
  if Zahl in [1,37] then farbe := clblue else
  farbe := clyellow;
  Listbox1.Items.InsertObject(0,IntToStr(Zahl), Pointer(farbe));
end;
ListBox1.Items.EndUpdate; // <--
Mit BeginUpdate/EndUpdate sagtst Du Windows, dass Du jetzt viele Sachen ändern möchtest und Windows sich vorerst raushalten soll (Sonst will Windows bei jeder Änderung die Listbox neu zeichnen).

Mit Add() statt Insert() sparst Du Dir jede Menge Speicheroperationen. Bei Insert müssen ja jedesmal sämtliche Referenzen nach hinten geschoben werden, damit vorne wieder Platz ist. Bei 100.000 Verschiebungen kommt da ganz schön was zusammen.

Gruß
xaromz

MrKnogge 27. Jun 2005 00:50

Re: Problem beim erzeugen von Zufallszahlen 100.000<
 
Zitat:

Zitat von xaromz
Delphi-Quellcode:
ListBox1.Items.BeginUpdate; // <--
for i:=1 to StrToInt64(Edit1.Text) do//////hier wird bestimmt wieviel Zz erzeugt werden
begin
  Zahl :=random(7)+1;
  meineListe.Add(IntToStr(Zahl)); // <--
  if Zahl in [1,37] then farbe := clblue else
  farbe := clyellow;
  Listbox1.Items.InsertObject(0,IntToStr(Zahl), Pointer(farbe));
end;
ListBox1.Items.EndUpdate; // <--

Wenn du nun auch noch statt
Delphi-Quellcode:
for i:=1 to StrToInt64(Edit1.Text) do
Delphi-Quellcode:
for i := StrToInt64(Edit1.Text) downto 1 do
schreibst, ist dein Code
1. nochmal etwas schneller, und
2. hast du sogar die gleiche reihenfolge der zufallszahlen wie bei deinem code.
(normalweiße egal da ja alle zahlen zufällig sind, es soll aber doch Leute geben für die mit random erzeugte zufallszahlen nicht zufällig sind)

Um wieder auf deinen Code zurück zu kommen:
Delphi-Quellcode:
...
Zahl :=random(7)+1;
...
if Zahl in [1,37] then farbe := clblue else // deine Zahl wird nie 37 sein
...
ob der code schneller wird, wenn du die 37 wegnimmst, weiß ich nicht, aber da der fall sowieso nicht eintrifft, würd ich sie rauslöschen.

gruss

x000x 27. Jun 2005 01:29

Re: Problem beim erzeugen von Zufallszahlen 100.000<
 
Moin moin,

brauchst du wirklich eine ListBox für die Einträge? (Ich kann mir nicht vorstellen,
dass jemand 100000 Einträge durchscrollt)
Wenn du im Programm nur die farbe + zahl brauchst, nehme doch nen array...
(Mit Begin + EndUpdate gehts bissel schneller, aber zufrieden wirst du nicht sein)

Delphi-Quellcode:
type
   TMyListe = Record
      Zahl : Integer;
      Farbe : TColor;
   end;

procedure TForm1.SpeedButton8Click(Sender: TObject);
Var i     : Integer;
    MyListe : array of TMyListe;
begin
   randomize;
   for i:=1 to StrToInt64(Edit1.Text) do begin
      SetLength( MyListe, i );
      MyListe[Pred(i)].Zahl := random(7)+1;
      if MyListe[Pred(i)].Zahl in [1,3,7] then
         MyListe[Pred(i)].farbe := clblue
      else
         MyListe[Pred(i)].farbe := clyellow;
   end;
   ShowMessage('Fertig :o)');
   Finalize(MyListe);
end;
Wenn du hier 100000 einträgst und auf deinen button klickst,
bekommst du die meldung schon, wenn du die maus los lässt...

Ist es evtl. eine alternative?

Sharky 27. Jun 2005 06:50

Re: Problem beim erzeugen von Zufallszahlen 100.000<
 
Hai x000x,

Zitat:

Zitat von x000x
...
Delphi-Quellcode:
...
begin
   randomize;
   for i:=1 to StrToInt64(Edit1.Text) do begin
      SetLength( MyListe, i );
....
....

Es sollte in jedem Fall vermieden werden das Array innerhalb der Schleife zu vergrößern.
Wen ein Dyn-Array vergrößert wird passiert jedes mal folgendes:
1. Es wird neuer Speicher der benötigten größe reserviert
2. Die Daten werden vom alten Speicherbereich in den neuen kopiert
3. Der alte Speicherbereich wird freigegeben

Da ja vor dem durchlaufen der Schleife die notwendige größe des Arrays bekannt ist sollte dieses auch nur einmal gesetzt werden.

Ach ja: Dyn-Arrays beginnen immer beim Index 0. Ein SetLength(MyListe, 10) ist also ein Array [0..9] of MyListe. Das muss bei den zugriffen berücksichtigt werden.

jfheins 27. Jun 2005 06:57

Re: Problem beim erzeugen von Zufallszahlen 100.000<
 
Also besser so:
Delphi-Quellcode:
 //  randomize; Ab ins onFormCreate damit !
      SetLength( MyListe, StrToInt64(Edit1.Text));
   for i:=0 to Pred (StrToInt64(Edit1.Text)) do
begin
      MyListe[i].Zahl := random(7)+1;
      if MyListe[i].Zahl in [1,3,7] then
         MyListe[i].farbe := clblue
      else
         MyListe[i].farbe := clyellow;
   end;
   ShowMessage('Fertig :o)');
   Finalize(MyListe);
(da sind auch die ganzen Pred()'s weg ... ;)

Hallo_Thomas 27. Jun 2005 21:36

Re: Problem beim erzeugen von Zufallszahlen 100.000<
 
@ x000x

Sicherlich ist es etwas übertrieben alle 100.000 Zahlen darzustellen , sicherlich würden auch die letzten 20 Zahlen reichen, ich überlegst mir noch.


@jfheins,Sharky,x000x

Der Lösungsansatz ist meiner Meinung nach auf alle Fälle wesentlich besser!


Nun bin ich noch nicht ganz so bewandert wie kopiere ich die Zahlen von der Array MyListe in die Stringliste meineListe, Die bestimmung der Farben benötige ich nur für die Listbox zur besseren Unterscheidung? Hier folgt noch mal die Gleiche Frage, wie Füge/Kopiere ich diese Zahlen mit der Farbe in die Listbox ein?

Jarmen_Kell 27. Jun 2005 21:54

Re: Problem beim erzeugen von Zufallszahlen 100.000<
 
Das ist das Problem meiner Meinung nach.
Für die Ausgabe müsstest du das alles wieder hinüberkopieren und man hat imho nichts gewonnen.
Also zahlen in MyListe durchlaufen lassen und dann

Listbox1.Items.InsertObject(0,IntToStr(MyListe[I].Zahl), Pointer(MyListe[I].farbe));

Da brauch ich ja wohl keine Delphi Tags ....

Edit: Puh oder vielleicht geht das auch direkt mit Pointerchen. In diesem Fall wird ja vermutlich immer etwas neues reserviert ... oder ist das auch schon ein Pointer?

Hallo_Thomas 28. Jun 2005 19:29

Re: Problem beim erzeugen von Zufallszahlen 100.000<
 
Irgendwie bekomme ich die Zahlen immer noch nicht schneller in die Stringlist.


Kann man vielleicht die Zufallszahlen als String erzeugen?
IntToStr frisst ja doch ganz schön an Ressourcen.


Delphi-Quellcode:
MyListe[i].Zahl := IntToStr(random(7)+1);


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:41 Uhr.
Seite 1 von 2  1 2      

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