Il existe donc plusieurs façons de créer un booléen aléatoire en C #:
- Utilisation de Random.Next ():
rand.Next(2) == 0
- Utilisation de Random.NextDouble ():
rand.NextDouble() > 0.5
Y a-t-il vraiment une différence? Si tel est le cas, lequel a réellement les meilleures performances? Ou y a-t-il une autre façon que je n'ai pas vue, qui pourrait être encore plus rapide?
c#
performance
random
boolean
timedt
la source
la source
NextBytes
pour pré-remplir un tableau d'octets, l'utiliserBitArray
pour le transformer en une collection de booléens et récupérer ces booléens de aQueue
jusqu'à ce qu'il soit vidé, puis répétez le processus. Avec cette méthode, vous n'utilisez le randomiseur qu'une seule fois, donc toute surcharge qu'il crée ne se produit que lorsque vous remplissez la file d'attente. Cela peut être utile lorsqu'il s'agit d'un générateur de nombres aléatoires sécurisé plutôt que de laRandom
classe régulière .NextBytes
, donc c'est étonnamment lentbuffer[i] = (byte)(this.InternalSample() % 256);
- Je suppose que c'est ce dont vous parlez, qu'ils auraient pu prendre cet entier aléatoire et le diviser en 3 octets , remplissant le tableau d'octets avec environ 1/3 du travail. Je me demande s'il y avait une raison à cela ou s'il s'agissait simplement d'un oubli des développeurs.Réponses:
La première option -
rand.Next(2)
exécute en coulisses le code suivant:if (maxValue < 0) { throw new ArgumentOutOfRangeException("maxValue", Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", new object[] { "maxValue" })); } return (int) (this.Sample() * maxValue);
et pour la deuxième option -
rand.NextDouble()
:return this.Sample();
Étant donné que la première option contient la
maxValue
validation, la multiplication et la conversion, la deuxième option est probablement plus rapide .la source
Petite amélioration pour la deuxième option :
Selon MSDN
public virtual double NextDouble()
Retour
Donc, si vous voulez une booléenne aléatoire uniformément répartie, vous devez utiliser
>= 0.5
rand.NextDouble() >= 0.5
la source
Le plus rapide. L'appel de la méthode
Random.Next
a le moins de frais généraux. La méthode d'extension ci-dessous fonctionne 20% plus vite queRandom.NextDouble() > 0.5
et 35% plus vite queRandom.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] }
Plus rapide que le plus rapide. Il est possible de générer des booléens aléatoires avec la
Random
classe encore plus rapidement, en utilisant des astuces. Les 31 bits significatifs d'un généréint
peuvent être utilisés pour 31 productions booléennes ultérieures. La mise en œuvre ci-dessous est 40% plus rapide que celle précédemment déclarée comme la plus rapide.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; } }
la source
J'ai fait des tests avec un chronomètre. 100 000 itérations:
System.Random rnd = new System.Random(); if (rnd.Next(2) == 0) trues++;
Les processeurs aiment les entiers, donc la méthode Next (2) était plus rapide. 3700 contre 7500 ms, ce qui est assez substantiel. Aussi: je pense que les nombres aléatoires peuvent être un goulot d'étranglement, j'ai créé environ 50 images dans Unity, même avec une petite scène qui ralentissait sensiblement mon système, donc j'espérais aussi trouver une méthode pour créer un booléen aléatoire. Alors j'ai aussi essayé
if (System.DateTime.Now.Millisecond % 2 == 0) trues++;
mais l'appel d'une fonction statique était encore plus lent avec 9 600 ms. Ça vaut le coup. Enfin, j'ai sauté la comparaison et créé seulement 100000 valeurs aléatoires, pour m'assurer que la comparaison int vs double n'influençait pas le temps écoulé, mais le résultat était à peu près le même.
la source
DateTime.UtcNow
, c'est beaucoup plus rapide queDateTime.Now
.