Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Buffers;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Runtime.CompilerServices;
- using static System.Int64;
- Int32 passes = 0;
- PrimeSieve sieve = default;
- Stopwatch watch = Stopwatch.StartNew();
- while (watch.ElapsedMilliseconds < 10000)
- {
- sieve = new PrimeSieve(1000000);
- sieve.RunSieve();
- passes++;
- }
- watch.Stop();
- sieve.PrintResults(false, watch.Elapsed.TotalSeconds, passes);
- public readonly ref struct PrimeSieve
- {
- private readonly Int32 size;
- private readonly Span<Int64> bits;
- private readonly Int64[] data;
- private static readonly Dictionary<Int32, Int32> Factors = new()
- {
- { 10, 1 },
- { 100, 25 },
- { 1000, 168 },
- { 10000, 1229 },
- { 100000, 9592 },
- { 1000000, 78498 },
- { 10000000, 664579 },
- { 100000000, 5761455 }
- };
- public PrimeSieve(Int32 size)
- {
- this.size = size;
- data = ArrayPool<Int64>.Shared.Rent(size >> 6);
- bits = data.AsSpan();
- bits.Fill(MaxValue);
- }
- public Int32 CountPrimes()
- {
- Int32 count = 1;
- for (Int32 index = 3; index <= size; index++)
- {
- if (GetBit(index)) count++;
- }
- return count;
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)] private Boolean GetBit(Int32 index) => index % 2 != 0 && (bits[index >> 6] & (1 << (index >> 1))) != 0;
- [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ClearBit(Int32 index) => bits[index >> 6] &= ~(1 << (index >> 1));
- public void RunSieve()
- {
- Int32 factor = 3;
- Int32 q = (Int32) Math.Sqrt(size);
- while (factor < q)
- {
- for (Int32 num = factor; num <= size; num++)
- {
- if (GetBit(num))
- {
- factor = num;
- break;
- }
- }
- Int32 factorTimes2 = factor << 1;
- for (Int32 num = factor + factorTimes2; num <= size; num += factorTimes2) ClearBit(num);
- factor += 2;
- }
- ArrayPool<Int64>.Shared.Return(data);
- }
- public Boolean ValidateResults()
- {
- if (Factors.ContainsKey(size)) return Factors[size] == CountPrimes();
- return false;
- }
- public void PrintResults(Boolean showResults, Double duration, Int32 passes)
- {
- if (showResults) Console.Write("2, ");
- Int32 count = 1;
- for (Int32 num = 3; num <= size; num++)
- {
- if (GetBit(num))
- {
- if (showResults) Console.Write(num + ", ");
- count++;
- }
- }
- if (showResults) Console.WriteLine("");
- Console.WriteLine("Passes: " + passes + ", Time: " + duration + ", Avg: " + (duration/passes) + ", Limit: " + size + ", Count: " + count + ", Valid: " + ValidateResults());
- Console.ReadKey();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement