.net frame work 4.72 比 .net6性能低?

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快。

阅读 1.1k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进