web-dev-qa-db-ja.com

ランダムなブール値を生成する最速の方法

したがって、C#でランダムboolを作成する方法はいくつかあります。

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

本当に違いはありますか?もしそうなら、実際にどれがより良いパフォーマンスを持っていますか?または、私が見なかった別の方法がありますか?それはさらに速いかもしれませんか?

70
timedt

最初のオプション-Rand.Next(2)は、バックグラウンドで次のコードを実行します。

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

および2番目のオプション-Rand.NextDouble()の場合:

_return this.Sample();
_

最初のオプションにはmaxValue検証、乗算、およびキャストが含まれているため、2番目のオプションのほうがおそらく高速です

64
Aviran Cohen

secondオプションの小さな機能強化

[〜#〜] 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 |

50
DaRich

ストップウォッチでテストを実行しました。 100,000回の反復:

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

CPUは整数が好きなので、Next(2)メソッドの方が高速でした。 3,700ミリ秒と7,500ミリ秒。これは非常に重要です。また、乱数はボトルネックになる可能性があると思います.Unityでフレームごとに約50個作成しました。システムが著しく遅くなった小さなシーンでも、ランダムboolを作成する方法を見つけたいと思っていました。だから私も試しました

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

しかし、静的関数の呼び出しは9,600ミリ秒でさらに遅くなりました。試してみる価値。最後に、intとdoubleの比較が経過時間に影響を及ぼさないようにするために、比較をスキップして100,000個のランダムな値のみを作成しましたが、結果はほぼ同じでした。

5

最速。メソッドの呼び出し _Random.Next_ はオーバーヘッドが少ない。以下の拡張メソッドは、Random.NextDouble() > 0.5より20%高速で、Random.Next(2) == 0より35%高速です。

_public static bool NextBoolean(this Random random)
{
    return random.Next() > (Int32.MaxValue / 2);
    // Next() returns an int in the range [0..Int32.MaxValue]
}
_

最速より高速です。トリックを使用することにより、Randomクラスでランダムなブール値をさらに高速に生成することができます。生成されたintの31の有効ビットは、後続の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;
    }
}
_
0
Theodor Zoulias