Overview : 2000만개 자연수중 소수 찾기 속도
사용법 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using System.Threading.Tasks; private static IList<int> GetPrimeListWithParallel(IList<int> numbers) { var primeNumbers = new ConcurrentBag<int>(); //ConcurrentBag Parallel.ForEach(numbers, number => { if (IsPrime(number)) { primeNumbers.Add(number); } }); return primeNumbers.ToList(); } |
Sample :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Collections.Concurrent; using System.Diagnostics; namespace ConsoleTest { class Program { static void Main(string[] args) { // 2 million int limit = 2_000_000; //int limit = 2000; List<int> numbers = Enumerable.Range(0, limit).ToList(); Stopwatch watch = Stopwatch.StartNew(); IList<int> primeNumbersFromForeach = GetPrimeList(numbers); watch.Stop(); Stopwatch watchForParallel = Stopwatch.StartNew(); IList<int> primeNumbersFromParallelForeach = GetPrimeListWithParallel(numbers); watchForParallel.Stop(); Console.WriteLine($"Classical foreach loop | 소수들 : {primeNumbersFromForeach.Count} | 걸린시간 : {watch.ElapsedMilliseconds} ms."); Console.WriteLine($"Parallel.ForEach loop | 소수들 : {primeNumbersFromParallelForeach.Count} | 걸린시간 : {watchForParallel.ElapsedMilliseconds} ms."); //Console.WriteLine($"Classical foreach loop | 소수들 :"); //primeNumbersFromForeach.Where(numberWrite).ToList(); //Console.WriteLine($"Parallel.ForEach loop | 소수들 :"); //primeNumbersFromParallelForeach.Where(numberWrite).ToList(); Console.WriteLine("Press any key to exit."); Console.ReadLine(); } /// <summary> /// GetPrimeList returns Prime numbers by using sequential ForEach /// </summary> /// <param name="inputs"></param> /// <returns></returns> private static IList<int> GetPrimeList(IList<int> numbers) => numbers.Where(IsPrime).ToList(); // /// <summary> /// GetPrimeListWithParallel returns Prime numbers by using Parallel.ForEach /// </summary> /// <param name="numbers"></param> /// <returns></returns> private static IList<int> GetPrimeListWithParallel(IList<int> numbers) { var primeNumbers = new ConcurrentBag<int>(); //ConcurrentBag Parallel.ForEach(numbers, number => { if (IsPrime(number)) { primeNumbers.Add(number); } }); return primeNumbers.ToList(); } /// <summary> /// IsPrime returns true if number is Prime, else false.(https://en.wikipedia.org/wiki/Prime_number) /// 어떤 자연수n이 소수임을 판정하기 위해선 뉴트n 까지의 수 중 1을 제외하고 그 자연수의 약수가 있는지 확인하면 된다. /// </summary> /// <param name="number"></param> /// <returns></returns> private static bool IsPrime(int number) { if (number <= 2) //0,1,2 제외 { return false; } for (var divisor = 2; divisor <= Math.Sqrt(number); divisor++) { //Console.WriteLine($"number : {number} | divisor : {divisor} | Math.Sqrt(number) : {Math.Sqrt(number)} | number % divisor {number % divisor} "); if (number % divisor == 0) { //약수 있다. return false; } //약수 없다. =>true } return true; } /// <summary> /// 남은소수 나열 /// </summary> /// <param name="number"></param> private static bool numberWrite(int number) { Console.WriteLine($"남은소수 : {number}"); return true; } } } |
1 2 3 4 5 |
Classical foreach loop | 소수들 : 148932 | 걸린시간 : 1257 ms. Parallel.ForEach loop | 소수들 : 148932 | 걸린시간 : 363 ms. Press any key to exit. |