Depois de brincar com números binários em C#, agora é a vez dos primos.
Como você calcularia os números primos, por iteração simples ou usando o método chamado Crivo de Erastóstenes? Qual dá mais trabalho para codificar? Qual o de melhor desempenho? E, finalmente, por que não usar - ou usar - processamento paralelo para o cálculo? Quando devemos usar um ou outro método?
Quem consegue corrigir esse código, no tocante ao processamento paralelo?
O primeiro que realizar essa proeza será mencionado já sei, fiote... grande coisa aqui no site.
O meu código é:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Primo
{
class Program
{
static List<int> primos = new List<int>();
static void Main(string[] args)
{
Console.Write("Digite um número até 2³¹ - 1: ");
int n = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("\nn = {0}", n);
DateTime inicio = DateTime.Now;
for (int i = 2; i <= n; i++)
{
if (TestarPrimoOtimizado(i)) primos.Add(i);
}
Console.WriteLine("\nUsando TestarPrimoOtimizado demorou {0} "
+ "para processar e temos {1} primos no intervalo... o maior deles é {2}",
DateTime.Now - inicio, primos.Count, primos[primos.Count - 1]);
primos.Clear();
inicio = DateTime.Now;
for (int i = 2; i <= n; i++)
{
if (TestarPrimo(i)) primos.Add(i);
}
Console.WriteLine("\nUsando TestarPrimo demorou {0} "
+ "para processar e temos {1} primos no intervalo... o maior deles é {2}",
DateTime.Now - inicio, primos.Count, primos[primos.Count - 1]);
primos.Clear();
inicio = DateTime.Now;
Parallel.For(2, n, item =>
{
if (TestarPrimo(item)) primos.Add(item);
}
);
Console.WriteLine("\nUsando Parallel.For demorou {0} "
+ "para processar e temos {1} primos no intervalo... o maior deles é {2}",
DateTime.Now - inicio, primos.Count, primos[primos.Count - 1]);
Console.ReadKey();
}
private static bool TestarPrimo(int n)
{
bool primo = true;
for (int i = 2; i <= (int)Math.Sqrt(n); i++)
{
if (n % i == 0)
{
primo = false;
break;
}
}
return primo;
}
private static bool TestarPrimoOtimizado(int n)
{
bool primo = true;
foreach (var item in primos)
{
if (n < Math.Pow(item, 2)) break;
if (n % item == 0)
{
primo = false;
break;
}
}
return primo;
}
}
}