Итак, есть несколько способов создания случайного bool в C #:
- Использование Random.Next ():
rand.Next(2) == 0
- Использование Random.NextDouble ():
rand.NextDouble() > 0.5
Есть ли разница? Если да, то какой на самом деле имеет лучшую производительность? Или есть другой способ, которого я не видел, он может быть даже быстрее?
c#
performance
random
boolean
timedt
источник
источник
NextBytes
для предварительного заполнения байтового массива, использовать егоBitArray
для преобразования в коллекцию логических значений и извлекать эти логические значения из aQueue
до тех пор, пока он не будет очищен, а затем повторить процесс. В этом методе вы используете рандомизатор только один раз, поэтому любые накладные расходы, которые он создает, возникают только тогда, когда вы пополняете очередь. Это может быть полезно при работе с безопасным генератором случайных чисел, а не с обычнымRandom
классом.NextBytes
, так что она на удивление медленнаяbuffer[i] = (byte)(this.InternalSample() % 256);
- Я предполагаю, что это то, о чем вы говорите, что они могли взять это случайное целое число и разделить его на 3 байта , заполняя массив байтов примерно на 1/3 работы. Интересно, была ли для этого причина или это просто упущение со стороны разработчиков.Ответы:
Первый вариант -
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
проверку, умножение и приведение, второй вариант, вероятно, быстрее .источник
Небольшое улучшение для второго варианта :
Согласно MSDN
public virtual double NextDouble()
возвращается
Поэтому, если вам нужен равномерно распределенный случайный логический объект, вы должны использовать
>= 0.5
rand.NextDouble() >= 0.5
источник
Самый быстрый. При вызове метода
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; } }
источник
Я проводил тесты с секундомером. 100000 итераций:
System.Random rnd = new System.Random(); if (rnd.Next(2) == 0) trues++;
ЦП любят целые числа, поэтому метод Next (2) был быстрее. 3700 против 7500 мс, что довольно много. Также: я думаю, что случайные числа могут быть узким местом, я создавал около 50 на каждый кадр в Unity, даже с крошечной сценой, которая заметно замедляла мою систему, поэтому я также надеялся найти метод для создания случайного bool. Так что я тоже попробовал
if (System.DateTime.Now.Millisecond % 2 == 0) trues++;
но вызов статической функции был еще медленнее - 9600 мс. Стоит попробовать. Наконец, я пропустил сравнение и создал только 100 000 случайных значений, чтобы убедиться, что сравнение int и double не влияет на прошедшее время, но результат был почти таким же.
источник
DateTime.UtcNow
, это намного быстрее, чемDateTime.Now
.