'난수생성'에 해당되는 글 1건

  1. 2016.07.02 C# 난수생성 - Random 클래스 사용하기
개발팁2016. 7. 2. 13:28

C# 에서 난수값을 생성하기 위해 사용하는게 Random 클래스인데,

다른 언어에 비해 사용법이 간단하다.

 

Random rnd = new Random();

int val = rnd.Next(1, 100);

 

Random 클래스의 생성자는

 

void Random();

void Random(int seed);

 

2가지가 있는데, 보통 생성자 없이 사용하면, 시간을 seed 로 사용하게 된다.

seed 값을 지정하여,

Random rnd = new Random(DateTime.Now.Millisecond);

이렇게 사용하기도 한다.

seed 값을 고정값을 사용할경우에는, 항상 생성되는 random 값이 동일한 값이 나오게 된다.

 

난수를 생성하는 메서드는 3가지가 있다.

Next() - int 타입의 난수 발생

NextDouble() - double 타입의 난수 발생

NextBytes() - byte 배열의 난수 발생

 

Next 메서드는 3가지 형태로 사용이 가능하다.

1. Next(void) - int 타입의 0 이상의 난수를 발생한다.

2. Next(int maxValue) - 0 이상 maxValue 미만의 난수를 발생한다.

3. Next(int minValue, int maxValue) - minValue 이상 maxValue 미만의 난수를 발생한다. 음수도 가능.

 

여기서 주의할 점은,

난수 범위를 지정할때, 상한범위는 위에저 지정한 maxValue 이라는 값은 절대 나오지 않는다는 것이다.

rnd.Next(1, 100) 이라고 했을때 나올수 있는 난수는 1 ~ 99 까지이다, 절대 100은 나오지 않기 때문에,

사용시에 주의해서 사용해야 한다.

 

위 3가지 int 형 난수 발생시 성능을 한번 테스트 해보았다.

0 ~ 9 까지의 난수를 1000만번 발생시키는 테스트를 해보았다.

1. val = rnd.Next(0, 10);     // 테스트 1

2. val = rnd.Next(10);        // 테스트 2

3. val = rnd.Next() % 10;    // 테스트 3

 

이 3가지는 모두 0 ~ 9 사이의 난수를 발생하는 방법이다.

 

 

// 난수 마지막값은 발생하지 않는것을 확인하기 위해, 배열길이를 11개로 설정
int[] arrVal = new int[11] {0,0,0,0,0,0,0,0,0,0,0};

Random rnd = new Random();
int val;

var stopwatch = new Stopwatch(); // elapsed time 체크를 위해 stopwatch 사용


stopwatch.Start();

 

for (int i = 0; i < 10000000; i++)
{
 val = rnd.Next(0, 10);       // 테스트 1
 //val = rnd.Next(10);        // 테스트 2
 //val = rnd.Next() % 10;    // 테스트 3

 arrVal[val]++;
}

 

stopwatch.Stop();

 

this.txtElapTime.Text = stopwatch.ElapsedMilliseconds.ToString();

this.txtVal0.Text = arrVal[0].ToString();
this.txtVal1.Text = arrVal[1].ToString();
this.txtVal2.Text = arrVal[2].ToString();
this.txtVal3.Text = arrVal[3].ToString();
this.txtVal4.Text = arrVal[4].ToString();
this.txtVal5.Text = arrVal[5].ToString();
this.txtVal6.Text = arrVal[6].ToString();
this.txtVal7.Text = arrVal[7].ToString();
this.txtVal8.Text = arrVal[8].ToString();
this.txtVal9.Text = arrVal[9].ToString();
this.txtVal10.Text = arrVal[10].ToString(); // 마지막값 10은 절대 발생하지 않는다.

 


 

1. rnd.Next(0, 10) 을 사용하여, 1000만개의 난수를 발생하는 시간은 보통 280 ~ 300ms 가 소요.

 

 

2. val = rnd.Next(10) 을 사용하여, 1000만개의 난수를 발생하는 시간은 보통 180 ~ 190ms 가 소요.

 

 

3. rnd.Next() % 10 을 사용하여, 1000만개의 난수를 발생하는 시간은 보통 145 ~ 155ms 가 소요.

 

 

 

이정도면, 큰 차이가 없다고 볼수도 있지만, 미세하게 나마 퍼포먼스 면에서 차이를 보였다.

int Next(void) 가 가장 빨랐고,

int Next(int maxValue) 가 두번째,

int Next(int minValue, int maxValue) 가 가장 느렸다.

 

테스트에 사용된 프로젝트 파일을 다운받아서 확인해보십시요.

 

RandomTest.zip

 

 

 

Posted by 헝개