112 votes

Moyen le plus rapide pour générer un booléen aléatoire

Il existe plusieurs façons de créer un booléen aléatoire en C# :

  • En utilisant Random.Next() : rand.Next(2) == 0
  • En utilisant Random.NextDouble() : rand.NextDouble() > 0.5

Y a-t-il vraiment une différence? Si oui, lequel offre réellement de meilleures performances? Ou existe-t-il une autre méthode que je n'ai pas vue, qui pourrait être encore plus rapide ?

83voto

Aviran Points 1722

La première option - rand.Next(2) exécute en arrière-plan 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 une validation de maxValue, une multiplication et une conversion, la deuxième option est probablement plus rapide.

82voto

DaRich Points 777

Petite amélioration pour la deuxième option:

Selon MSDN

public virtual double NextDouble()

retourne

Un nombre de type double précision supérieur ou égal à 0,0 et inférieur à 1,0.

Donc, si vous voulez un booléen aléatoire uniformément réparti, vous devriez utiliser >= 0.5

rand.NextDouble() >= 0.5

Plage 1 : [0.0 ... 0.5[
Plage 2 : [0.5 ... 1.0[
|Plage 1| = |Plage 2|

25voto

Theodor Zoulias Points 1088

Le plus rapide. Appeler la méthode Random.Next a le moins d'overhead. La méthode d'extension ci-dessous s'exécute 20% plus rapidement que Random.NextDouble() > 0.5, et 35% plus rapidement que Random.Next(2) == 0.

public static bool NextBoolean(this Random random)
{
    return random.Next() > (Int32.MaxValue / 2);
    // Next() renvoie un int dans la plage [0..Int32.MaxValue]
}

Encore plus rapide que le plus rapide. Il est possible de générer des booléens aléatoires avec la classe Random encore plus rapidement, en utilisant des astuces. Les 31 bits significatifs d'un int généré peuvent être utilisés pour 31 productions booléennes consécutives. L'implémentation 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;
    }
}

10voto

J'ai effectué 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. 3 700 contre 7 500 ms, ce qui est assez substantiel. Aussi : Je pense que les nombres aléatoires peuvent être un goulot d'étranglement, j'en ai créé environ 50 à chaque image dans Unity, même avec une scène minuscule qui ralentissait sensiblement mon système, donc j'espérais aussi trouver une méthode pour créer un booléen aléatoire. J'ai donc également essayé

if (System.DateTime.Now.Millisecond % 2 == 0)
       trues++;

mais appeler une fonction statique était encore plus lent avec 9 600 ms. Un essai qui valait le coup. Enfin, j'ai sauté la comparaison et j'ai simplement créé 100 000 valeurs aléatoires, pour m'assurer que la comparaison entre int et double n'influait pas sur le temps écoulé, mais le résultat était à peu près le même.

-1voto

stom Points 2477

Basé sur les réponses ici, Voici le code que j'ai utilisé pour générer une valeur aléatoire bool.

  Random rand = new Random();
  bool randomBool = rand.NextDouble() >= 0.5;

Références:

Générer un booléen aléatoire

https://stackoverflow.com/a/28763727/2218697

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X