FrameWork
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace FindPrimeNumber
{
internal class Program
{
static int participantCount = Environment.ProcessorCount;
static int maxScope = int.MaxValue;
static int workCount = participantCount * 4;
static string directory = "temp";
static SemaphoreSlim smCompute;
static string filePath = "result.txt";
static Dictionary<int, string> dic;
static void Main()
{
Directory.CreateDirectory(directory);
dic = new Dictionary<int, string>();
smCompute = new SemaphoreSlim(participantCount, participantCount);
var sw = new Stopwatch();
Console.WriteLine("最大值");
int.TryParse(Console.ReadLine(), out maxScope);
Console.WriteLine($"2-{maxScope}");
sw.Start();
Run().Wait();
sw.Stop();
Console.WriteLine(sw.Elapsed.TotalSeconds);
Console.ReadLine();
}
static async Task Run()
{
int block = maxScope / workCount;
int rest = maxScope % workCount;
Task[] tasks = new Task[workCount];
Parallel.For(0, workCount, i =>
{
smCompute.Wait();
tasks[i] = Task.Run(() =>
{
try
{
int from = i == 0 ? i * block + 2 : i * block;
int to = i == workCount - 1 ? (i + 1) * block + rest : (i + 1) * block + 1;
var l = to - from;
var a = new int[l];
for (int j = 0; j < l; j++)
{
a[j] = from + j;
}
for (int j = 0; j < l; j++)
{
if (a[j] == 0)
continue;
if (IsPrime(a[j]))
{
for (int k = j + a[j]; k < l && k > 0; k += a[j])
{
a[k] = 0;
}
}
else
a[j] = 0;
}
Save(a, l, i);
smCompute.Release();
}
catch (Exception x)
{
Console.WriteLine(x);
}
});
});
await Task.WhenAll(tasks);
}
static Task Save(int[] nums, int l, int i)
{
return Task.Run(() =>
{
int[] a = nums ?? throw new ArgumentNullException(nameof(nums));
var dish = new StringBuilder();
int qf = 0;
for (int j = 0; j < l; j++)
{
if (nums[j] != 0)
{
qf = qf == 0 ? nums[j] : qf;
dish.AppendLine(a[j].ToString());
}
}
GC.Collect();
var nPath = Path.Combine(directory, $"{i}{filePath}");
dic.Add(qf, nPath);
File.WriteAllText(nPath, dish.ToString(), Encoding.ASCII);
});
}
#region ...
static void GetPrimeNumbers(int[] nums, int length)
{
for (int i = 0; i < length; i++)
{
.net6.0 if (nums[i] == 0)
continue;
if (IsPrime(nums[i]))
{
for (int k = i + nums[i]; k < length && k > 0; k += nums[i])
{
nums[k] = 0;
}
}
else
nums[i] = 0;
}
}
#endregion
#region IsPrime
static bool IsPrime(int num)
{
if (num < 2)
return false;
for (int i = 2; i <= Math.Sqrt(num); i++)
{
if (num % i == 0)
{
return false;
}
}
return true;
}
#endregion
}
}
Net6.0
using System.Buffers;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Text;
int participantCount = Environment.ProcessorCount;
int maxScope = int.MaxValue;
int workCount = participantCount * 4;
string directory = "temp";
Directory.CreateDirectory(directory);
string filePath = "result.txt";
Dictionary<int, string> dic = new Dictionary<int, string>();
var smCompute = new SemaphoreSlim(participantCount, participantCount);
var sw = new Stopwatch();
Console.WriteLine("最大值");
Console.WriteLine($"2-{int.TryParse(Console.ReadLine(), out maxScope)}");
sw.Start();
await Run();
sw.Stop();
Console.WriteLine(sw.Elapsed.TotalSeconds);
Console.ReadLine();
async Task Run()
{
int block = maxScope / workCount;
int rest = maxScope % workCount;
Task[] tasks = new Task[workCount];
Parallel.For(0, workCount, i =>
{
smCompute.Wait();
tasks[i] = Task.Run(() =>
{
try
{
int from = i == 0 ? i * block + 2 : i * block;
int to = i == workCount - 1 ? (i + 1) * block + rest : (i + 1) * block + 1;
var l = to - from;
var a = ArrayPool<int>.Shared.Rent(l);
for (int i = 0; i < l; i++)
{
a[i] = from + i;
}
for (int j = 0; j < l; j++)
{
if (a[j] == 0)
continue;
if (IsPrime(a[j]))
{
for (int k = j + a[j]; k < l && k > 0; k += a[j])
{
a[k] = 0;
}
}
else
a[j] = 0;
}
Save(a, l, i);
smCompute.Release();
}
catch (Exception x)
{
Console.WriteLine(x);
}
});
});
await Task.WhenAll(tasks);
}
Task Save(int[] nums, int l, int i)
{
return Task.Run(() =>
{
int[] a = nums ?? throw new ArgumentNullException(nameof(nums));
var dish = new DefaultInterpolatedStringHandler();
int qf = 0;
for (int i = 0; i < l; i++)
{
if (nums[i] != 0)
{
qf = qf == 0 ? nums[i] : qf;
dish.AppendLiteral(a[i].ToString() + "\n");
}
}
GC.Collect();
var nPath = Path.Combine(directory, $"{i}{filePath}");
dic.Add(qf, nPath);
ArrayPool<int>.Shared.Return(nums, true);
File.WriteAllText(nPath, dish.ToStringAndClear(), Encoding.ASCII);
});
}
#region ...
void GetPrimeNumbers(int[] nums, int length)
{
for (int i = 0; i < length; i++)
{
if (nums[i] == 0)
continue;
if (IsPrime(nums[i]))
{
for (int k = i + nums[i]; k < length && k > 0; k += nums[i])
{
nums[k] = 0;
}
}
else
nums[i] = 0;
}
}
#endregion
#region IsPrime
bool IsPrime(int num)
{
if (num < 2)
return false;
for (int i = 2; i <= Math.Sqrt(num); i++)
{
if (num % i == 0)
{
return false;
}
}
return true;
}
#endregion
计算2至1600竟然出乎意料。 采用同样的代码,编译运行结果依然是FrameWork快。