Jest więc kilka sposobów tworzenia losowej wartości bool w C #:
- Korzystanie z Random.Next ():
rand.Next(2) == 0
- Korzystanie z Random.NextDouble ():
rand.NextDouble() > 0.5
Czy naprawdę jest różnica? Jeśli tak, to który z nich ma lepszą wydajność? A może jest inny sposób, którego nie widziałem, który mógłby być jeszcze szybszy?
c#
performance
random
boolean
timedt
źródło
źródło
NextBytes
do wstępnego wypełnienia tablicy bajtów, użyj jejBitArray
do przekształcenia jej w kolekcję wartości logicznych i odzyskaj te wartości logiczne z aQueue
aż do opróżnienia, a następnie powtórz proces. Dzięki tej metodzie randomizera używasz tylko raz, więc wszelkie narzuty, które tworzy, pojawiają się tylko wtedy, gdy uzupełniasz kolejkę. Może to być przydatne w przypadku bezpiecznego generatora liczb losowych, a nie zwykłejRandom
klasy.NextBytes
, więc jest zaskakująco wolnybuffer[i] = (byte)(this.InternalSample() % 256);
- Zakładam, że o tym mówisz, że mogli wziąć tę losową liczbę całkowitą i podzielić ją na 3 bajty , zapełniając tablicę bajtów około 1/3 pracy. Zastanawiam się, czy był ku temu powód, czy tylko niedopatrzenie ze strony deweloperów.Odpowiedzi:
Pierwsza opcja -
rand.Next(2)
Wykonuje za kulisami następujący kod:if (maxValue < 0) { throw new ArgumentOutOfRangeException("maxValue", Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", new object[] { "maxValue" })); } return (int) (this.Sample() * maxValue);
a dla drugiej opcji -
rand.NextDouble()
:return this.Sample();
Ponieważ pierwsza opcja obejmuje
maxValue
walidację, mnożenie i rzutowanie, druga opcja jest prawdopodobnie szybsza .źródło
Małe rozszerzenie dla drugiej opcji :
Według MSDN
public virtual double NextDouble()
zwroty
Więc jeśli chcesz równomiernie rozłożyć losowy bool, powinieneś użyć
>= 0.5
rand.NextDouble() >= 0.5
źródło
Najszybszy. Wywołanie metody
Random.Next
ma mniejszy narzut. Poniższa metoda rozszerzenia działa o 20% szybciej niżRandom.NextDouble() > 0.5
io 35% szybciej niżRandom.Next(2) == 0
.public static bool NextBoolean(this Random random) { return random.Next() > (Int32.MaxValue / 2); // Next() returns an int in the range [0..Int32.MaxValue] }
Szybciej niż najszybciej. Możliwe jest
Random
jeszcze szybsze generowanie losowych wartości logicznych z klasą za pomocą sztuczek. 31 znaczących bitów wygenerowanegoint
kodu można wykorzystać do 31 kolejnych produkcji logicznych. Poniższa implementacja jest o 40% szybsza niż wcześniej deklarowana jako najszybsza.public class RandomEx : Random { private uint _boolBits; public RandomEx() : base() { } public RandomEx(int seed) : base(seed) { } public bool NextBoolean() { _boolBits >>= 1; if (_boolBits <= 1) _boolBits = (uint)~this.Next(); return (_boolBits & 1) == 0; } }
źródło
Przeprowadziłem testy ze stoperem. 100 000 iteracji:
System.Random rnd = new System.Random(); if (rnd.Next(2) == 0) trues++;
Procesory takie jak liczby całkowite, więc metoda Next (2) była szybsza. 3700 w porównaniu z 7500 ms, co jest dość znaczące. Ponadto: Myślę, że losowe liczby mogą być wąskim gardłem, stworzyłem około 50 każdej klatki w Unity, nawet z małą sceną, która wyraźnie spowolniła mój system, więc miałem również nadzieję, że znajdę metodę tworzenia losowego bool. Więc też próbowałem
if (System.DateTime.Now.Millisecond % 2 == 0) trues++;
ale wywołanie funkcji statycznej było jeszcze wolniejsze i wynosiło 9600 ms. Warto spróbować. W końcu pominąłem porównanie i utworzyłem tylko 100 000 losowych wartości, aby upewnić się, że porównanie int vs double nie wpłynęło na upływający czas, ale wynik był prawie taki sam.
źródło
DateTime.UtcNow
, jest znacznie szybszy niżDateTime.Now
.