Подтвердить что ты не робот

Самый быстрый способ генерации случайного логического

Итак, существует несколько способов создания случайного bool в С#:

  • Использование Random.Next(): rand.Next(2) == 0
  • Использование Random.NextDouble(): rand.NextDouble() > 0.5

Есть ли разница? Если да, то какая из них на самом деле имеет лучшую производительность? Или есть другой способ, который я не видел, может быть еще быстрее?

4b9b3361

Ответ 1

Первый вариант - rand.Next(2) выполняет за кадром следующий код:

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

а для второго варианта - rand.NextDouble():

return this.Sample();

Поскольку первая опция содержит проверку, умножение и приведение maxValue, вторая опция, вероятно, быстрее.

Ответ 2

Небольшое усиление для опции второй:

Согласно MSDN

public virtual double NextDouble()

возвращает

Число с плавающей запятой с двойной точностью, большее или равное 0,0, и менее 1,0.

Итак, если вы хотите равномерно распределить случайный bool, вы должны использовать >= 0.5

rand.NextDouble() >= 0.5

Диапазон 1: [0.0... 0.5 [
Диапазон 2: [0,5... 1,0 [
| Диапазон 1 | = | Диапазон 2 |

Ответ 3

Я провел тесты с секундомером. 100 000 итераций:

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

Процессоры любят целые числа, поэтому метод Next (2) был быстрее. 3700 против 7500 мс, что весьма существенно. Кроме того: я думаю, что случайные числа могут быть узким местом, я создал около 50 каждого кадра в Unity, даже с крошечной сценой, которая заметно замедляет мою систему, поэтому я также надеялся найти метод для создания случайного бул. Так я тоже попробовал

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

но вызов статической функции был еще медленнее с 9600 мс. Стоит выстрел. Наконец, я пропустил сравнение и создал только 100 000 случайных значений, чтобы убедиться, что сравнение int и double не влияло на прошедшее время, но результат был почти таким же.

Ответ 4

Самый быстрый. Вызов метода Random.Next имеет меньше накладных расходов. Приведенный ниже метод расширения работает на 20% быстрее, чем Random.NextDouble() > 0.5, и на 35% быстрее, чем 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]
}

Быстрее, чем быстрее. Можно сгенерировать случайные логические значения с помощью класса Random еще быстрее, используя приемы. 31 старших биты генерируемого int могут быть использованы в течение 31 последующих логических производств. Реализация сильфона на 40% быстрее, чем ранее заявленная как самая быстрая.

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;
    }
}