web-dev-qa-db-fra.com

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

Il y a 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 oui, lequel a réellement la meilleure performance? Ou y a-t-il un autre moyen que je n'ai pas vu, qui pourrait être encore plus rapide?

70
timedt

Le première option - Rand.Next(2) exécute en coulisse le code suivant:

if (maxValue < 0)
{
    throw new ArgumentOutOfRangeException("maxValue",
        Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", new object[] { "maxValue" }));
}
return (int) (this.Sample() * maxValue);

et pour le deuxième option - Rand.NextDouble():

return this.Sample();

Puisque la première option contient maxValue validation, multiplication et conversion, la deuxième option est probablement plus rapide.

64
Aviran Cohen

Petite amélioration pour la deuxième option :

Selon MSDN

public virtual double NextDouble()

résultats

Nombre en virgule flottante double précision supérieur ou égal à 0,0 et inférieur à 1,0.

Donc, si vous voulez un booléel bien réparti, vous devez utiliser >= 0.5

Rand.NextDouble() >= 0.5

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

50
DaRich

J'ai exécuté des tests avec chronomètre. 100 000 itérations:

System.Random rnd = new System.Random();
if (rnd.Next(2) == 0)
     trues++;

Les CPU aiment les entiers, la méthode Next (2) était donc plus rapide. 3 700 contre 7 500 ms, ce qui est assez considérable. Aussi: je pense que les nombres aléatoires peuvent être un goulot d'étranglement, j'ai créé environ 50 images par image dans Unity, même avec une scène minuscule qui a sensiblement ralenti mon système. J'espérais également 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 appeler une fonction statique était encore plus lent avec 9 600 ms. Ça vaut le coup. Enfin, j'ai ignoré la comparaison et créé seulement 100 000 valeurs aléatoires, afin de m'assurer que la comparaison int/double n'influencait pas le temps écoulé, mais le résultat était à peu près le même.

5
Frederik Steinmetz

Le plus rapide. Appel de la méthode Random.Next a le moins de temps système. La méthode d'extension ci-dessous s'exécute 20% plus vite 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() 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 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 ultérieures. 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;
    }
}
0
Theodor Zoulias