Randomおそるべし。前回のrand.Next()で極めたと思っていた。
例えば以下のようなことをやるとはまる。
int[] randomArray = new int[10];
for (int i = 0; i < 10; i++) {
Random rand = new Random();
randomArray[i] = rand.Next(100);
}
これはたぶん、randomArrayの要素はすべて同じになる。
なぜかというと、new Random()でインスタンスを作ると時間をシードとして生成されるが、時間がms単位だからだそうだ。
上記のような単純なコードの場合は各ループで1msも経つわけないので全部同じシードで初期化されるという。まあ、上記の例だとrandをforの外で定義してやればいいという話だが、例えば
public void hoge() {
Random rand = new Random();
// なんらかの処理
// でもそんなに時間はかからない
}
public void hogehoge() {
for (int i = 0; i < 10; i++) {
hoge();
}
}
ってな感じにしたとき、hoge()内のrandは何回やっても同じことをやることになるのでぜんぜん意味がない感じになる。
仕方がないので下記のようにした。
class CustomRandom {
static private Random rand = null;
static public Random GetRandom() {
if (rand == null) {
rand = new Random();
}
return rand;
}
}
------------------------------------------------
public void hoge() {
Random rand = CustomRandom.GetRandom();
// おなじみシングルトンということで。
}
同じインスタンスに対してNextしてやれば、まあ問題ないかなと。本当はもっと賢くしたほうがいいかもしれないけど、それは未来に託す。
以上
ピンバック: [C#]ちゃんと使わないとgomiになるRandom « Ex.QuelLENcode Blog