Advertisement
Guest User

PrimeSieveCS

a guest
Apr 11th, 2021
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.02 KB | None | 0 0
  1. using System;
  2. using System.Buffers;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.Runtime.CompilerServices;
  6.  
  7. using static System.Int64;
  8.  
  9. Int32      passes = 0;
  10. PrimeSieve sieve  = default;
  11.  
  12. Stopwatch watch = Stopwatch.StartNew();
  13.  
  14. while (watch.ElapsedMilliseconds < 10000)
  15. {
  16.     sieve = new PrimeSieve(1000000);
  17.     sieve.RunSieve();
  18.     passes++;
  19. }
  20.  
  21. watch.Stop();
  22.  
  23. sieve.PrintResults(false, watch.Elapsed.TotalSeconds, passes);
  24.  
  25. public readonly ref struct PrimeSieve
  26. {
  27.     private readonly Int32  size;
  28.  
  29.     private readonly Span<Int64> bits;
  30.     private readonly Int64[]     data;
  31.  
  32.     private static readonly Dictionary<Int32, Int32> Factors = new()
  33.     {
  34.         { 10, 1 },
  35.         { 100, 25 },
  36.         { 1000, 168 },
  37.         { 10000, 1229 },
  38.         { 100000, 9592 },
  39.         { 1000000, 78498 },
  40.         { 10000000, 664579 },
  41.         { 100000000, 5761455 }
  42.     };
  43.  
  44.     public PrimeSieve(Int32 size)
  45.     {
  46.         this.size = size;
  47.  
  48.         data = ArrayPool<Int64>.Shared.Rent(size >> 6);
  49.         bits = data.AsSpan();
  50.         bits.Fill(MaxValue);
  51.     }
  52.  
  53.     public Int32 CountPrimes()
  54.     {
  55.         Int32 count = 1;
  56.  
  57.         for (Int32 index = 3; index <= size; index++)
  58.         {
  59.             if (GetBit(index)) count++;
  60.         }
  61.  
  62.         return count;
  63.     }
  64.  
  65.     [MethodImpl(MethodImplOptions.AggressiveInlining)] private Boolean GetBit(Int32 index) => index % 2 != 0 && (bits[index >> 6] & (1 << (index >> 1))) != 0;
  66.     [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ClearBit(Int32 index) => bits[index >> 6] &= ~(1 << (index >> 1));
  67.  
  68.     public void RunSieve()
  69.     {
  70.         Int32 factor = 3;
  71.         Int32 q      = (Int32) Math.Sqrt(size);
  72.  
  73.         while (factor < q)
  74.         {
  75.             for (Int32 num = factor; num <= size; num++)
  76.             {
  77.                 if (GetBit(num))
  78.                 {
  79.                     factor = num;
  80.                     break;
  81.                 }
  82.             }
  83.  
  84.             Int32 factorTimes2 = factor << 1;
  85.  
  86.             for (Int32 num = factor + factorTimes2; num <= size; num += factorTimes2) ClearBit(num);
  87.  
  88.             factor += 2;
  89.         }
  90.  
  91.         ArrayPool<Int64>.Shared.Return(data);
  92.     }
  93.  
  94.     public Boolean ValidateResults()
  95.     {
  96.         if (Factors.ContainsKey(size)) return Factors[size] == CountPrimes();
  97.  
  98.         return false;
  99.     }
  100.  
  101.     public void PrintResults(Boolean showResults, Double duration, Int32 passes)
  102.     {
  103.         if (showResults) Console.Write("2, ");
  104.  
  105.         Int32 count = 1;
  106.  
  107.         for (Int32 num = 3; num <= size; num++)
  108.         {
  109.             if (GetBit(num))
  110.             {
  111.                 if (showResults) Console.Write(num + ", ");
  112.                 count++;
  113.             }
  114.         }
  115.  
  116.         if (showResults) Console.WriteLine("");
  117.  
  118.         Console.WriteLine("Passes: " + passes + ", Time: " + duration + ", Avg: " + (duration/passes) + ", Limit: " + size + ", Count: " + count + ", Valid: " + ValidateResults());
  119.         Console.ReadKey();
  120.     }
  121. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement