したがって、C#でランダムブール値を作成する方法はいくつかあります。
- Random.Next()の使用:
rand.Next(2) == 0
- Random.NextDouble()の使用:
rand.NextDouble() > 0.5
本当に違いはありますか?もしそうなら、どちらが実際に優れたパフォーマンスを持っていますか?それとも私が見なかった別の方法がありますか、それはさらに速いかもしれませんか?
したがって、C#でランダムブール値を作成する方法はいくつかあります。
rand.Next(2) == 0
rand.NextDouble() > 0.5
本当に違いはありますか?もしそうなら、どちらが実際に優れたパフォーマンスを持っていますか?それとも私が見なかった別の方法がありますか、それはさらに速いかもしれませんか?
NextBytes
バイト配列を事前入力し、BitArray
それをブール値のコレクションに変換し、Queue
空になるまでそれらのブール値を取得してから繰り返すのが私の推測です。プロセス。この方法では、ランダマイザーを1回しか使用しないため、ランダマイザーが作成するオーバーヘッドは、キューを補充したときにのみ発生します。これは、通常の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);
そして2番目のオプションの場合- rand.NextDouble()
:
return this.Sample();
最初のオプションにはmaxValue
検証、乗算、キャストが含まれているため、2番目のオプションの方がおそらく高速です。
最速。メソッド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
トリックを使用することで、クラスでランダムなブール値をさらに高速に生成することができます。生成された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;
}
}
ストップウォッチでテストを実行しました。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,600msとさらに遅くなりました。試してみる価値。最後に、intとdoubleの比較が経過時間に影響を与えないように、比較をスキップして100,000のランダム値のみを作成しましたが、結果はほぼ同じでした。
DateTime.UtcNow
、よりもはるかに高速ですDateTime.Now
。