Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Random() zu langsam? (https://www.delphipraxis.net/100853-random-zu-langsam.html)

Kuonrat 4. Okt 2007 17:43


Random() zu langsam?
 
Hallo, ich möchte eine möglichst große Anzahl an Zufallszahlen generieren, mein Problem ist jedoch die Dauer die das Programm dafür benötigt. Das Auslesen des Arrays in eine TListBox geht mittlerweile sehr schnell dank .BeginUpdate.
Das reine füllen des Arrays dauert aber viel zu lange. Schon für 100.000 Zahlen brauch er 1min 30sek. Und ich kann mir nicht helfen warum.
Delphi-Quellcode:
procedure TFach.generate;
var i : Integer;
begin

SetLength(Items, Number+1);

for i := 0 to Number do
  begin
  Items[i] := Random(Number)+1;
  end;

end;
Man sagte mir ich soll .NET deaktivieren, ich hab leider keine Idee wie ich das machen soll, noch ob es überhaupt etwas bringt. Ich benutze Delphi 2005 Prof.

DP-Maintenance 4. Okt 2007 17:46

DP-Maintenance
 
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Object-Pascal / Delphi-Language" verschoben.
Delphi-Frage

Khabarakh 4. Okt 2007 18:09

Re: Random() zu langsam?
 
lol? Folgender Code benötigt nicht einmal eine Millisekunde:
Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows, DateUtils;

const
  n = 100000;
var
  i: Integer;
  Start: Cardinal;
  Data: array of Integer;
begin
  Start := GetTickCount;
  Randomize;
  SetLength(Data, n);
  for i := 0 to n - 1 do
    Data[i] := Random(n);
  Writeln(GetTickCount - Start);
  Readln;
end.
Zitat:

Zitat von Kuonrat
Man sagte mir ich soll .NET deaktivieren, ich hab leider keine Idee wie ich das machen soll, noch ob es überhaupt etwas bringt. Ich benutze Delphi 2005 Prof.

Das Projekt ist aber schon Delphi.Win32 und nicht Delphi.Net, oder?

Sharky 4. Okt 2007 18:13

Re: Random() zu langsam?
 
Zitat:

Zitat von Khabarakh
lol?

Hai Kraberakh,

dein "Lachen" mag ja lustig sein.... aber sage dem Fragesteller doch bitte auch warum Du das machst!
Alles andere ist nämlich unnötig.

Danke :stupid:

3_of_8 4. Okt 2007 18:14

Re: Random() zu langsam?
 
Es ist *nicht* ratsam, ständig neuen Speicher zu reservieren. (mit SetLength)

Besser einmal reservieren und dann so lassen.

DeddyH 4. Okt 2007 18:16

Re: Random() zu langsam?
 
Zitat:

Zitat von 3_of_8
Es ist *nicht* ratsam, ständig neuen Speicher zu reservieren. (mit SetLength)

Besser einmal reservieren und dann so lassen.

Hast Du mehr gesehen als ich? Wo wird denn ständig neuer Speicher reserviert?

Matze 4. Okt 2007 18:18

Re: Random() zu langsam?
 
Zitat:

Zitat von Sharky
aber sage dem Fragesteller doch bitte auch warum Du das machst!

Sebastians Code unterscheidet sich eigentlich nicht vom Code des Fragestellers bis auf die winzige Addition, die jedoch nicht so ins Gewicht fallen kann. Ich denke, daher lacht er.

Vermutlich benötigen andere Code-Teile so lange.

Kuonrat 4. Okt 2007 18:33

Re: Random() zu langsam?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab es jetzt mal seperat direkt auf einem Button ausprobiert. Da waren es 6 Sekunden für 1.000.000 Zahlen. Ich hab es wohl irgendwo mit meiner schlechten OOP vergeigt. Trotzdem hab ich das gefühl 6 Sekunden sei zu langsam. Im IRC hat man mir 16-17ms gesagt, bräuchten sie. Selber Quellcode.
Ich versuch erstmal das ganze flüssiger zu machen, ich häng mal mein Projekt an. Ich erwarte nicht, dass das jemand durchguckt. Aber vielleicht sieht ja jemand direkt auf Anhieb etwas, was auf garkeinen Fall sein darf. :P

shmia 4. Okt 2007 18:37

Re: Random() zu langsam?
 
Die Ursache für die schlechte Performance ist TListBox.Items.
Die Klasse ist zwar von TStrings abgeleitet, speichert seine Daten aber nicht selbst, sondern
per Windows Messages im darunterliegenden Control. Das Versenden von hundertausenden Messages braucht eben Zeit.
Abhilfe:
Daten in einer TStringList erzeugen und dann mit Assign auf die TListbox kopieren.

Kuonrat 4. Okt 2007 19:06

Re: Random() zu langsam?
 
Okay, danke für den Tipp. Werd eich beachten. Die Fehlerursache liegt bei der zeitmessung. Ich war so KLUK 'QueryPerformanceFrequency' zu benutzten statt GetTickCount. Das war die ultimative Performance Bremse. Jetzt erreiche ich endlich die Werte die ich haben möchte. :)

brinkee 4. Okt 2007 19:08

Re: Random() zu langsam?
 
Hehe, das ist natürlich gut :D

Dax 4. Okt 2007 19:11

Re: Random() zu langsam?
 
Zitat:

Zitat von Kuonrat
Ich war so KLUK 'QueryPerformanceFrequency' zu benutzten statt GetTickCount. Das war die ultimative Performance Bremse.

Das halte ich für ein Gerücht. Selbst in einer VM braucht ein Aufruf von QueryPerformance* nur jeweils drei Mikrosekunden.

3_of_8 4. Okt 2007 19:32

Re: Random() zu langsam?
 
Delphi-Quellcode:
procedure TFach.generate;
var i : Integer;
begin

SetLength(Items, Number+1);

for i := 0 to Number do
  begin
  Items[i] := Random(Number)+1;
  end;

end;
Hab mich wohl versehen, das auf den ersten Blick so ausgesehen, als würde er generate sehr oft aufrufen und dabei jedesmal neuen Speicher reservieren. Ich sollte wohl genauer hinschauen.

Kuonrat 4. Okt 2007 19:46

Re: Random() zu langsam?
 
Zitat:

Zitat von Dax
Zitat:

Zitat von Kuonrat
Ich war so KLUK 'QueryPerformanceFrequency' zu benutzten statt GetTickCount. Das war die ultimative Performance Bremse.

Das halte ich für ein Gerücht. Selbst in einer VM braucht ein Aufruf von QueryPerformance* nur jeweils drei Mikrosekunden.

Okay, es mag eher daran gelegen haben, das ich die Zeit des gesammten Buttons gemessen habe. Dadurch zieht sich auch die Progressbar hinaus. Umklammer ich nur das Generieren an sich, erhalte ich selbige Werte.
Was soviel bedeutet, dass ich weiterhin am Auslesen in der GUIa rbeiten muss.

Dax 4. Okt 2007 19:48

Re: Random() zu langsam?
 
Nein, das bedeutet, dass du deine Daten nicht in der GUI speichern solltest, denn dafür ist die GUI nicht gemacht worden ;)

Kuonrat 4. Okt 2007 20:03

Re: Random() zu langsam?
 
Na meine Daten sind doch zur Zeit im Array, welches sich in der Fachklasse TFach befindet. Auslesen tat ich mit einer Schleife. Und das wollte ich jetzt so ändern, dass die Daten in TStringList gespeichert werden und mittels List.Assign anfügen. Oder hab ich das falsch verstanden?

Hawkeye219 4. Okt 2007 20:19

Re: Random() zu langsam?
 
Hallo,

du hast die Zahlen doch bereits in einem Array abgelegt, warum dann noch einmal in einer Stringliste und anschließend in der ListBox? Du kannst eine TListBox im virtuellen Modus betreiben (ListBox.Style = lbVirtual). Für jedes Element wird dann ein OnData-Ereignis ausgelöst, in dem du die anzuzeigenden Daten bereitstellen mußt.

Wie bist du eigentlich auf die Idee gekommen, 100000+ Elemente in einer Listbox darzustellen? Das Scrollen (und genaue Positionieren) in einer solchen Datenmenge macht keinen Spaß.

Gruß Hawkeye

Kuonrat 4. Okt 2007 20:23

Re: Random() zu langsam?
 
Ich möchte nur zahlen generieren, diese mit verschiedenen verfahren sortieren, und die benötigte zeit vergleichen.

Kuonrat 4. Okt 2007 22:22

Re: Random() zu langsam?
 
Zitat:

Zitat von shmia
Die Ursache für die schlechte Performance ist TListBox.Items.
Die Klasse ist zwar von TStrings abgeleitet, speichert seine Daten aber nicht selbst, sondern
per Windows Messages im darunterliegenden Control. Das Versenden von hundertausenden Messages braucht eben Zeit.
Abhilfe:
Daten in einer TStringList erzeugen und dann mit Assign auf die TListbox kopieren.

Hab ich ausprobiert, dauer exakt genauso lang.

shmia 5. Okt 2007 08:54

Re: Random() zu langsam?
 
Zitat:

Zitat von Kuonrat
Zitat:

Zitat von shmia
Die Ursache für die schlechte Performance ist TListBox.Items.
Die Klasse ist zwar von TStrings abgeleitet, speichert seine Daten aber nicht selbst, sondern
per Windows Messages im darunterliegenden Control. Das Versenden von hundertausenden Messages braucht eben Zeit.
Abhilfe:
Daten in einer TStringList erzeugen und dann mit Assign auf die TListbox kopieren.

Hab ich ausprobiert, dauer exakt genauso lang.

Du hast recht; hier meine Messwerte zum Füllen mit 100000 Strings à 4 Zeichen:
Code:
TStringList: 62ms
TMemo:     11.1s
TListBox:  1.75s
man sieht, dass TStringList um Welten schneller ist.
Es dauert allerdings gleich lang, wenn man eine TListBox direkt befüllt oder zuerst TStringList befüllt und dann auf TListbox "assigned".
(eigentlich logisch; in beiden Fällen müssen 100000 Messages verschickt werden)
ABER: wenn man auf die Strings zugreift um z.B. sie zu sortieren, dann macht das einen Unterschied
von Faktor 30 ob man den Sortiervorgang auf einer StringList ausführt oder auf TListBox.Items.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:02 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz