96

所以有几种方法可以在 C# 中创建随机布尔值:

  • 使用 Random.Next():rand.Next(2) == 0
  • 使用 Random.NextDouble():rand.NextDouble() > 0.5

真的有区别吗?如果是这样,哪一个实际上具有更好的性能?还是有另一种我没有看到的方法,可能更快?

4

4 回答 4

76

一个选项-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验证、乘法和强制转换,因此第二个选项可能更快

于 2013-10-04T21:34:28.087 回答
72

第二个选项的小增强:

根据MSDN

public virtual double NextDouble()

返回

大于或等于 0.0 且小于 1.0 的双精度浮点数。

所以如果你想要一个均匀分布的随机布尔值,你应该使用>= 0.5

rand.NextDouble() >= 0.5

范围 1:[0.0 ... 0.5[
范围 2:[0.5 ... 1.0[
|范围 1| = |范围 2|

于 2015-02-27T11:12:19.170 回答
16

The fastest. Calling the method Random.Next has the less overhead. The extension method below runs 20% faster than Random.NextDouble() > 0.5, and 35% faster than 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]
}

Faster than the fastest. It is possible to generate random booleans with the Random class even faster, by using tricks. The 31 significant bits of a generated int can be used for 31 subsequent boolean productions. The implementation below is 40% faster than the previously declared as the fastest.

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;
    }
}
于 2019-06-26T16:11:30.467 回答
8

我用秒表进行了测试。100,000 次迭代:

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

CPU 喜欢整数,因此 Next(2) 方法更快。3,700 对 7,500 毫秒,这是相当可观的。另外:我认为随机数可能是一个瓶颈,我在 Unity 中每帧创建大约 50 个,即使有一个小场景明显减慢了我的系统,所以我也希望找到一种方法来创建随机布尔值。所以我也试过

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

但是调用静态函数的速度甚至更慢,需要 9,600 毫秒。值得一试。最后我跳过了比较,只创建了 100,000 个随机值,以确保 int 与 double 比较不会影响经过的时间,但结果几乎相同。

于 2018-12-13T12:44:40.617 回答