Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Random(2) in schnell (https://www.delphipraxis.net/89420-random-2-schnell.html)

glkgereon 30. Mär 2007 21:37


Random(2) in schnell
 
Hi,

Ich habe ein Programm in dem ich sehr oft eine 1:1 wahrscheinlichkeit berechnen muss.
nun stehe ich vor dem Problem das Random(2) vermutlich den größten Teil meiner Laufzeit in Anspruch nimmt....was etwas unbefriedigend ist.

Das Problem ist dass ich nicht genau testen kann wieviel Random in anspruch nimmt, da die benötigten Durchläufe direkt vom ergebnis von Random abhängen. Wenn ich also immer 1 nehme ist mein Programm zwar sofort durch, hat aber auch nur einen winzigen Bruchteil an durchläufen gehabt, wenn ich 0 nehme ist es eine endlosschleife.

Nun stellt sich natürlich die Frage nach alternativen...

Ich habe es bereits mit GetTickCount (Auflösung zu gering), QueryPerformanceFrequency (Nicht zufällig genug??? jedenfalls ne endlosschleife) und Mouse (u.ä. auch net zufällig genug) versucht...reicht aber alles nicht.

Was gäbe es noch an Alternativen?

SirThornberry 30. Mär 2007 21:42

Re: Random(1) in schnell
 
Wenn du "Random(1)" machst kannst du auch gleich 0 schreiben. Schau dir am besten mal die hilfe zu random an.

glkgereon 30. Mär 2007 21:43

Re: Random(1) in schnell
 
Zitat:

Zitat von SirThornberry
Wenn du "Random(1)" machst kannst du auch gleich 0 schreiben. Schau dir am besten mal die hilfe zu random an.

Schande über mich :duck: , ich meinte natürlich Random(2); :wall:

cruiser 30. Mär 2007 21:48

Re: Random(2) in schnell
 
Nur eine Idee... generiere eine Zufallszahl, mehrere Bytes, und speichere die Bitfolge in meinetwegen einem Array of Boolean. Das Array berechnest du dann halt alle 32, 64, whatever Durchläufe neu.

glkgereon 30. Mär 2007 22:19

Re: Random(2) in schnell
 
Zitat:

Zitat von cruiser
Nur eine Idee... generiere eine Zufallszahl, mehrere Bytes, und speichere die Bitfolge in meinetwegen einem Array of Boolean. Das Array berechnest du dann halt alle 32, 64, whatever Durchläufe neu.

Vielen Dank :-D
Das hat mich immerhin schonmal von 43 auf 36 Sekunden gebracht bei einem 32Bit Integer als Zwischenspeicher...
Nicht schlecht :thumb:
Leider scheint Random kein Int64 zu unterstützen :?

Sonst irgendwelche Ideen?

Dax 30. Mär 2007 22:20

Re: Random(2) in schnell
 
Benutz doch jeweils einen QPC-Ergebniswert als Quelle für 64 Bits. Oder benutz einen Mersenne Twister. Oder... ;)

glkgereon 30. Mär 2007 22:41

Re: Random(2) in schnell
 
Zitat:

Zitat von Dax
Benutz doch jeweils einen QPC-Ergebniswert als Quelle für 64 Bits. Oder benutz einen Mersenne Twister. Oder... ;)

Sry, aber QPC sagt mir gar nichts :?

Der Mersenne Twister hört sich interessant an...
Gibt es von dem eine Implementation in Delphi? *zu negaH schiel :wink: *

3_of_8 30. Mär 2007 22:51

Re: Random(2) in schnell
 
QPC ist QueryPerformanceCounter.

alzaimar 30. Mär 2007 23:06

Re: Random(2) in schnell
 
Zitat:

Zitat von glkgereon
Der Mersenne Twister hört sich interessant an...
Gibt es von dem eine Implementation in Delphi? *zu negaH schiel :wink: *

Der Mersenne Twister ist viel langsamer als das native Random von Delphi. Aber es gibt eine in Delphi.

Was willst du überhaupt machen?

Der_Unwissende 31. Mär 2007 09:06

Re: Random(2) in schnell
 
Zitat:

Zitat von glkgereon
Leider scheint Random kein Int64 zu unterstützen :?

Hi,
dafür unterstützt es als Ausgabe 80Bit-Extended Werte :wink:

Nikolas 31. Mär 2007 09:09

Re: Random(2) in schnell
 
Was machst du denn überhaupt mit den Zahlen? Vielleicht gibt es eine Möglichkeit, das Ganze anders anzusetzen.

Amateurprofi 31. Mär 2007 09:57

Re: Random(2) in schnell
 
Vielleicht liege ich jetzt völlig falsch, aber ich versuche es mal.

Du bist der Auffassung, die Nutzung der Random Funktion nähme zuviel Zeit in Anspruch.
Wenn das so sein sollte : Was macht Dein Programm, außer ausschließlich die Random-Funktion aufzurufen ?
Ein Aufruf Random(2) benötigt 24 CPU-Ticks (GetTickCount=16 CPU-Ticks)

QueryPerformanceFrequency ist als Alternative natürlich nicht tauglich, denn die liefert dir die Frequenz von QueryPerfomanceCounter, sollte also ein konstanter Wert sein.

Das Ergebnis von QueryPerformanceCounter wäre eine Alternative, allerdings braucht das ca. 2900 Ticks also mehr als 100 mal so viel wir Random(2).

Statt des lahmen QPC könntest Du den Time Stamp Counter direkt abfragen, aber auch das braucht 88 CPU-Ticks, also fast 4 mal so viel wie Random(2).

Delphi-Quellcode:
FUNCTION TimeStamp:Int64;
asm
   rdtsc
end;
Wenn du, was das Beitrag vermuten läßt, eine Zufallszahl im Bereich 0..1 haben möchtest könntest du das so realisieren

Delphi-Quellcode:
FUNCTION Random2:integer;
asm
   rdtsc
   and eax,1
end;
Wenn ich das alles völllig falsch verstanden habe, dann ignoriere das Obige bitte.

3_of_8 31. Mär 2007 10:09

Re: Random(2) in schnell
 
Zitat:

Zitat von Der_Unwissende
Zitat:

Zitat von glkgereon
Leider scheint Random kein Int64 zu unterstützen :?

Hi,
dafür unterstützt es als Ausgabe 80Bit-Extended Werte :wink:

Man sollte aber wahrscheinlich nur die Mantisse verwenden. Das Zero-Bit wird meißtens 1 sein und das Sign-Bit immer 0. Der Exponent wird denke ich auch nicht stark genug schwanken.

brechi 31. Mär 2007 10:28

Re: Random(2) in schnell
 
der Zufallsgenerator von Delphi mal in Assembler und für 1/0 optimiert:
Delphi-Quellcode:

  asm
    @@nochma:
    imul ecx, ecx, $8088405 // vielleicht hier mal experimentieren
    inc ecx
    //mov edx, ecx

    js @@ist1
// wenn 0 mache:
    nop

    jmp @@nochma
    @@ist1:
// wenn 1 mache:
    nop

    jmp @@nochma
  end;

negaH 31. Mär 2007 10:36

Re: Random(2) in schnell
 
Mersenne Twister kanste vergessen, zu langsam.

Aber zum Angang machst du mal was anders ;)

Erzeuge eine 323Bit Zufallszahl. Diese global speichern. Bei der Berechnung in deinen Funktionen dann diese Funktion

Delphi-Quellcode:
var
  Zufall: Caridnal = 0;

function RandomBit: Boolean;
begin
  Zufall := Zufall shr 1 or Zufall shl 31;
  Result := Odd(Zufall);
end;

initialization
  Randomize;
  Zufall := Random(MaxInt);
end.
Dies produziert zwar immer die gleiche Sequenz aus 32 Bits, aber dies spielt zur Einschätzung, um wieviel du durch die Optimierung deines RNGs an Zeit einsparen könntest, keine Rolle.

Im alten DEC war ein TRandom_LFSR mit Perioden von 2^32-1 bis 2^2032-1 bei dem der LFSR 128 mit Periode 2^128-1 ungefähr 43Mb/Sec auf einem P4 1.5GHz lief. Du könntest dir aus dem Source dieses LFSR extrahieren.

Gruß Hagen

glkgereon 31. Mär 2007 11:28

Re: Random(2) in schnell
 
Ok, ich denke es ist an der Zeit mal genauer den "Sinn" des Projektes zu erläutern.

Im Prinzip geht es um ein OnlineGame.
Bei diesem Spiel ist es möglich Waffen mithilfe von Edelsteinen zu veredeln. (Um Schaden zu erhöhen...)
Hierbei gibt es Waffenstufen von 0 bis 15.
Für jeden Up-Versuch wird ein Stein benötigt.
Es besteht eine 50%-Chance dass der Versuch erfolgreich ist (Stufe wird um eins erhöht)
Schlägt der Versuch fehl, wird die Stufe verringert (Allerdings nur falls die neue Stufe nicht unter 3 liegt...d.h. bei einem Fehlschlag bei Stufe 0,1,2 oder 3 bleibt alles wie es ist).

Ziel ist es einen Simulator dazu zu schreiben, welcher die Steine zählt die man braucht um eine Waffe von 0 auf 15 zu bringen.
Quelltext ist folgender:
Delphi-Quellcode:
while Akt<>Config.Ziel do //Akt = Aktuelle Stufe
begin
  if Rnd>31 then begin R:=Random(MaxInt); Rnd:=0; end; //Letztes Bit meines 32Bit Random-Werts => Neue Zahl
  if (R and (1 shl Rnd))<>0 then //Aktuelles Bit true?
    Inc(Akt) //Eins Hoch
  else if Akt>3 then Dec(Akt); //Sonst wenn Stufe>3 dann runter
  Inc(C); //Versuch zählen
  Inc(Rnd); //Nächstes Bit
end;
Ich hoffe es ist klar dass ein "nicht zufälliger zufallsgenerator" mir nicht weiterhilft :-)

Ein weiteres Problem, welches mir soeben aufgefallen ist ist der Array den ich für meine Ergebnisse nutze...
insgesamt sieht das so aus:
Delphi-Quellcode:
TUpper = class
// ...
  FRes64: array of Int64;
end;

procedure TUpper.Generate(Cnt: Int64);
var Akt, Rnd: Byte;
    C, Len: Int64;
    R: Integer;
begin
  Len:=Length(FRes64);
  Rnd:=255;
  R:=0;
  while Cnt>0 do
  begin
    Akt:=Config.Start;
    C:=0;
    while Akt<>Config.Ziel do
    begin
      if Rnd>31 then begin R:=Random(MaxInt); Rnd:=0; end;
      if (R and (1 shl Rnd))<>0 then
        Inc(Akt)
      else if Akt>3 then Dec(Akt);
      Inc(C);
      Inc(Rnd);
    end;
    if C>=Len then
    begin
      Len:=C+1;
      SetLength(FRes64,Len);
    end;
    Inc(FRes64[C]);
    Dec(Cnt);
  end;
end;
in anbetracht der Tatsache dass Random nur 22 Cycles benötigt, liegt es vielleicht doch eher am SetLength?
(Wie) kann man das optimieren?

Daher stellt sich mir nun die Frage ob man hier überhaupt noch groß optimieren kann...(Aber da vertrau ich ganz auf euch :wink: )
Im Moment braucht diese Funktion so wie sie da steht für 100.000.000 Durchläufe 386 Sekunden auf einem AMD 3000+ (seperater Thread, tpLower, Opera,Miranda usw im Hintergrund laufend)

Nikolas 31. Mär 2007 12:04

Re: Random(2) in schnell
 
Bei so einem Problem solltest du dich eher an einem Stochastiker wenden. Gut Möglich, dass du im Matheboard.de jemanden mit einer Lösung finden kannst. Du hast hier einen Random-Walk in einem beschränkten Intervall, vielleicht hat schon jemand eine analytische Lösung gefunden.

Der_Unwissende 31. Mär 2007 13:13

Re: Random(2) in schnell
 
Zitat:

Zitat von 3_of_8
Man sollte aber wahrscheinlich nur die Mantisse verwenden. Das Zero-Bit wird meißtens 1 sein und das Sign-Bit immer 0. Der Exponent wird denke ich auch nicht stark genug schwanken.

Warum sollte denn der Exponent nicht stark genug schwanken? Ich meine die Random-Funktion erzeugt recht gleichverteilt Zahlen zwischen 0 und 1 (idealerweise). Das wiederum heißt, dass alle negativen Exponenten recht gleichmässig verwendet werden können (oder übersehe ich etwas?), was wohl wieder ein Bit weniger bedeutet. Bleiben von den 80 Bit eines Extended immer noch 77 übrig. Das sind immer noch mehr Bits als bei einem Int64 nötig währen, die schwanken (Sinn und Nutzen mal außen vor)


Gruß Der Unwissende

3_of_8 31. Mär 2007 13:46

Re: Random(2) in schnell
 
Stimmt, wenn man das Sign-Bit des Exponenten rauslässt, könnte es gehen. Und man spart sich auch die Multiplikation, die man hat, wenn man das ganze in einen Integer umrechnet.

grenzgaenger 31. Mär 2007 20:37

Re: Random(2) in schnell
 
sag mal, was machst du eigentlich da?
Delphi-Quellcode:
if C>=Len then
    begin
      Len:=C+1;
      SetLength(FRes64,Len);
    end;
    Inc(FRes64[C]);
ich kann mir nicht vorstllen, dass du 2^32 ergebnisse auf dem bildschirm sehen möchtest. schränk das doch mal ein und bau dir eine vernünftige datenstruktur auf, anstatt immer den speicher umzumodeln...

glkgereon 31. Mär 2007 20:40

Re: Random(2) in schnell
 
Ich habe einen Array dieser Form:

Array[Anzahl an Steinen] = So oft vorgekommen

Wie soll ich es sonst machen?

grenzgaenger 31. Mär 2007 20:43

Re: Random(2) in schnell
 
wie soll denn deine ausgabe aussehen resp. wie sieht sie derzeit aus?

PS: du hast doch nur 15 steine, oder hab ich mich da verhört?

glkgereon 31. Mär 2007 20:46

Re: Random(2) in schnell
 
Eine Liste

Anzahl Steine: So oft Vorgekommen

bzw die liste als Balkendiagramm

jaa, die anzahl an steinen die verbaut wurden...
es gibt 15 stufen und jeder stein hat ja ne 50%-chance die zu erhöhen...
im schnitt sind es ca. 162 steine für 15 stufen.

grenzgaenger 31. Mär 2007 20:53

Re: Random(2) in schnell
 
dann hast du doch hier 'n array[0..14] oder array[1..15], da brauchste doch kein setlength, das kannste dir doch auch schon zuvor ausrechnen und den compiler sagen, wie gross das wird. wenn du der sache nicht traust, kannste ja auch noch 'n paar byte sicherheitsreserve drauflegen.

pass auf, dein progy wird noch zum turbo :wink:

ps: wenn du auch noch steine unterschiedlicher qualität hast, kannst 'n 2 dimensionales array erstellen, z.b. array[1..15, 0..300]; nach oben begrenzt, da du ja auch nicht unendlich spielen kannst ...

glkgereon 31. Mär 2007 20:55

Re: Random(2) in schnell
 
Zitat:

Zitat von grenzgaenger
dann hast du doch hier 'n array[0..14] oder array[1..15], da brauchste doch kein setlength, das kannste dir doch auch schon zuvor ausrechnen und den compiler sagen, wie gross das wird. wenn du der sache nicht traust, kannste ja auch noch 'n paar byte sicherheitsreserve drauflegen.

pass auf, dein progy wird noch zum turbo :wink:

ps: wenn du auch noch steine unterschiedlicher qualität hast, kannst 'n 2 dimensionales array erstellen, z.b. array[1..15, 0..300]; nach oben begrenzt, da du ja auch nicht unendlich spielen kannst ...

lies dir bitte nochmal meinen post durch wo ich erkläre wie das ganze funktioniert.

Ich will speichern wie oft ich wieviele steine insgesamt brauche...

grenzgaenger 31. Mär 2007 20:58

Re: Random(2) in schnell
 
wenn du für jeden level speichern willst, dann brauchste 'n array[1..15]. da kannste dann sagen inc(a[level]); und daraus kannste dann 'n wunderbares balkendiagramm zaubern :-)

PS: vermindern kannste den level dann mit dec(level);

grenzgaenger 31. Mär 2007 21:10

Re: Random(2) in schnell
 
hab mal 'n kleines demo zusammengebastelt:

Delphi-Quellcode:
program Project2;
{$APPTYPE CONSOLE}
uses sysutils;

var
 a: array[1..15] of integer;
 i, level: integer;
begin
 level := 1;
 randomize;
 while level < 16 do
 begin
  case random(2) of
   0: begin
       inc(a[level]);
       inc(level)
      end;
   1: begin
       if level > 3 then
        dec(level);
      end;
  end;
 end;
 for i := 1 to 15 do
  writeln(i:3,#9,a[i]);
 readln;
end.
optimierungen musste da noch selbst vornehmen, z.b. wenn 'de 'ne monte carlo methode mit implementieren möchtest....

glkgereon 31. Mär 2007 21:18

Re: Random(2) in schnell
 
Das ist aber nichts das was ich haben will!!! :wall:

grenzgaenger 31. Mär 2007 21:23

Re: Random(2) in schnell
 
was willste denn dann haben? dachte 'n auswertung, wieviele versuche du brauchst, um durch die jeweiligen level durchzusteigen? genau, das macht es, kannst natürlich noch verfeinern, z.b. mit wievielen versuchen du vergeblich angerant bist... musste halt noch 'ne zweite dimension aufmachen. wie vorhin beschrieben.

ansonsten, zeig doch mal deine ausgabe her? so wie in deinem obigen beispiel, kannste es ja nicht ausgeben... wird ja viel zu unübersichtlich...

PS: beim beispiel, hab ich keine balkengrafik gemacht, sondern halt 'ne ganz normale ausgabe, sollt eigentlich reichen... um das zu testen...

Nikolas 1. Apr 2007 08:50

Re: Random(2) in schnell
 
Ich habe mich mal etwas umgehört und Diesen Ansatz bekommen. Nur hab ich gerade keine Muße diese Matrix zu vereinfachen, ich geh aber davon aus, dass hier jemand einen Gaußschen Algo geschrieben hat, in den er diese Matrix recht schnell einbauen kann. Wer hat Lust darauf?

alzaimar 1. Apr 2007 09:32

Re: Random(2) in schnell
 
Das riecht einfach nach stinknormaler gaußscher Normalverteilung.

Aber die Frage ('Wie viele Versuche braucht man ...') ist schon falsch gestellt. Denn die Antwort kann man so geben: "Wenn man Glück hat, reichen 15 Versuche, hat man Pech, passiert es nie". Das ist das Wesen des Zufalls.

Die korrekte Frage würde lauten: "Wie viele Versuche braucht man im Mittel, damit das Zielereginis mit einer 90%igen Wahrscheinlichkeit auftritt?". Da es sich um eine Gaußsche Glockenkurve handelt (meine Annahme), muß man 'nur' ausrechnen(!), bei welchem X die Fläche unter der Kurve 90 ergibt.
Oder so ähnlich.

Mathematiker vor! (Ich krieg komischerweise immer Denk- und Schreibstörungen :roteyes: , wenn eine Volltextrecherche in einem Umkreis von 15km 70%ige Treffer bei der Suche nach dem Wort 'Wahrscheinlichkeit' ergibt :mrgreen: )

Nikolas 1. Apr 2007 09:37

Re: Random(2) in schnell
 
Das Ganze müsste eher eine Binomialverteilung sein. Das Problem ist aber, dass du hier nicht in beide Richtungen laufen darfst und das nach dem ersten erreichen des letzen Feldes abgebrochen wird. Diese beiden Einschränkungen machen alles etwas schwieriger :)

Hawkeye219 1. Apr 2007 10:10

Re: Random(2) in schnell
 
Hallo,

hier noch ein Ansatz zur Beschleunigung der Simulation: loop unrolling. Bei dieser Technik werden mehrere Schleifendurchläufe ausprogrammiert, was im aktuellen Fall die Verwaltung des zusätzlichen Bitzählers erspart. Weiterhin sollte die Anzahl der Sprungbefehle auf ein Minimum reduziert werden:

Delphi-Quellcode:
var
  [...]
  y : Byte;
begin
[...]
  Akt := Config.Start;
  if (Akt <> Config.Ziel) then
  repeat
    R := Random($10000);

    y := Ord(Odd(r));
    Inc (Akt, y - Ord(Akt > 3) shr y);
    Inc (C); if (Akt = Config.Ziel) THEN Break;

    y := Ord(Odd(r shr 1));
    Inc (Akt, y - Ord(Akt > 3) shr y);
    Inc (C); if (Akt = Config.Ziel) THEN Break;

    y := Ord(Odd(r shr 2));
    Inc (Akt, y - Ord(Akt > 3) shr y);
    Inc (C); if (Akt = Config.Ziel) THEN Break;

    [...]

    y := Ord(Odd(r shr 14));
    Inc (Akt, y - Ord(Akt > 3) shr y);
    Inc (C); if (Akt = Config.Ziel) THEN Break;

    y := Ord(Odd(r shr 15));
    Inc (Akt, y - Ord(Akt > 3) shr y);
    Inc (C); if (Akt = Config.Ziel) THEN Break;
  until False;
  [...]
end;
Eine solche Optimierung verbessert zwar die Laufzeit, nicht aber die Lesbarkeit des Quelltextes...

Gruß Hawkeye

DGL-luke 1. Apr 2007 10:23

Re: Random(2) in schnell
 
Jop, da fragt man die Stochastiker :)

Man kann das ganze als Bernoulli-Kette der Länge x sehen und dann die wahrscheinlcihkeit dafür ausrechnen, dass man mit diesen x Versuchen 15 Treffer landet.

Das wäre dann B(x;0,5;15) = (15 über x)0,5^x*0,5^(15-x) hmm... das lässt sich vereinfachen... (15 über x)0,5^(x+15-x) = (15 über x)0,5^15 wenn ich mich nicht irre. meine tabelle enthält leider nix für p=0,5.

Nikolas 1. Apr 2007 10:30

Re: Random(2) in schnell
 
Das klappt so leider nicht. Wenn du einmal daneben liegst, brauchst du zwei Treffer mehr, da deine Stufe nach unten gesetzt wird. Mit 15 Treffern landest du nicht auf Stufe 15, sondern sonstwo (z.B. auf der Null, wenn du immer abwechselnd triffst).
Auch fehlt bei dem Ansatz die Einschränkung, dass du nicht ins negative gehen darfst. Ich habe schon einen Ansatz (siehe ein paar Posts oben), habe nur keine Zeit, das mal auszurechnen.

glkgereon 1. Apr 2007 12:23

Re: Random(2) in schnell
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich muss ehrlich zugeben dass ich diesen Ansatz nicht verstehe...

Mein Ziel ist es im Prinzip ganz am Ende eine Liste zuhaben:
Anzahl Stein: Wahrscheinlichkeit

Die Durchschnittliche Anzahl ist mehr ein Nebenprodukt was man direkt noch mit ausrechnen kann :-)

[Edit]
Zur Verteilung... Die sieht so aus wie im Anhang (X = so oft vorgekommen, Y = Anzahl der Steine).

grenzgaenger 2. Apr 2007 08:10

Re: Random(2) in schnell
 
hallo greedy,

ich hab zwar immer noch keinen plan davon, was du auswerten willst, hätt aber 'ne kleine änderung im quellcode vorzuschlagen..

Delphi-Quellcode:
TUpper = class
// ...
  FRes64: array of cardinal; //<<-- reicht doch aus, und kann der rechner besser verarbeiten
end;

procedure TUpper.Generate(Cnt: Int64);
var Akt, Rnd: Byte;
    C, Len: cardinal; //<<-- reicht doch aus, und kann der rechner besser verarbeiten
    R: Integer;
begin
  Len:=Length(FRes64+100000); //<<-- hier gleich mehr byte reservieren
  Rnd:=255;
  R:=0;
  while Cnt>0 do
  begin
    Akt:=Config.Start;
    C:=0;
    while Akt<>Config.Ziel do
    begin
      if Rnd>31 then begin R:=Random(MaxInt); Rnd:=0; end;
      if (R and (1 shl Rnd))<>0 then
        Inc(Akt)
      else if Akt>3 then Dec(Akt);
      Inc(C);
      Inc(Rnd);
    end;
    if C>=Len then
    begin
      Len:=C+1;
      SetLength(FRes64,Len+100000); //<<-- hier gleich mehr byte reservieren
    end;
    Inc(FRes64[C]);
    Dec(Cnt);
  end;
end;
PS: bei mir werden ca. 4'000'000'000 random aufrufe in ein paar wenigen sekunden abgearbeitet... also, an random kanns nicht liegen..

glkgereon 2. Apr 2007 08:56

Re: Random(2) in schnell
 
Liste der Anhänge anzeigen (Anzahl: 2)
Also das mit 32Bit vs 64Bit habe ich auch schon ausprobiert.

Statt einem array of Int64 ein array of Integer zu nehmen bringt, es hat mich sehr erstaunt, keinen messbaren Performanceschub.
Ich habe es mehrmals gemessen, die Differenz war <2 Sekunden auf 5 Minuten.

Das mit dem SetLength ist eigentlich keine Schlechte Idee, auch wenn es hier an der falschen Stelle steht ;-)
das ganze muss eine Zeile höher.
Allerdings bringt auch dies keinen signifikanten Unterschied.

Len:=C+1; 43s für 10mio
Len:=C+100; 43s für 10mio
Len:=C+10000; 42s für 10mio


Übrigens ist mir eine Sache aufgefallen...
während folgende Abfrage:
Delphi-Quellcode:
if Random(2)=1 then
Eine ziemlich glatte Kurze hervorbringt, hat bei dieser Bedingung:
Delphi-Quellcode:
if Rnd>31 then begin R:=Random(MaxInt); Rnd:=1; end;
if (R and (1 shl Rnd))<>0 then
Die Kurve deutlich ausgeprägte Spitzen!
interessanterweise in 32er Abständen... :gruebel:
So wie das im Moment ist scheint diese Optimierung die zufällige Verteilung etwas aus dem Gleichgewicht zu bringen.

[Edit]
Jetzt versteh ich gar nix mehr. :shock:
Ist Cardinal schneller als Integer???
Delphi-Quellcode:
if Rnd>31 then begin R:=Random(High(R))+1; Rnd:=1; end;
mit Integer auf 10mio: 35s
mit Cardinal auf 10mio: 27s
:wiejetzt:

[Edit2]
Das Array hingegen auf Cardinal downzugraden brachte mich lediglich von 27 auf 26s.
Die sind wahrscheinlich auch eher im nur halb so kleinen Array begründet.

[Edit3]
Im Anhang mal ein ScreenShot von den "Zacken"...
btw scheinen es nicht 32er Abstände zu sein sonderen 31er.

Hawkeye219 2. Apr 2007 11:00

Re: Random(2) in schnell
 
Gereon, hast du meinen Vorschlag aus Beitrag #33 einmal geprüft? Das Code-Stück ersetzt lediglich die innere WHILE-Schleife deines Codes.

Gruß Hawkeye

glkgereon 2. Apr 2007 11:06

Re: Random(2) in schnell
 
Zitat:

Zitat von Hawkeye219
Gereon, hast du meinen Vorschlag aus Beitrag #33 einmal geprüft? Das Code-Stück ersetzt lediglich die innere WHILE-Schleife deines Codes.

Gruß Hawkeye

Ganz ehrlich würde ich so eine Lösung mit allen Mitteln vermeiden wollen :?

Aber ich probiere es gleich mal aus.

[Edit]
Die If-Anweisungen um Abzubrechen scheinen mehr Ticks zu brauchen als dei Auflösung der Schleife einbringt...
Es dauert 29s statt nur 27s.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:54 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