From 1cbf49c8b5923731d01f6906481229287301cd7c Mon Sep 17 00:00:00 2001 From: mlemanczyk Date: Sat, 11 Oct 2025 13:37:23 +0200 Subject: [PATCH] Small optimizations --- PerfectNumbers.Core/FactorEntry.cs | 21 +++++++++--- PerfectNumbers.Core/PartialFactorResult.cs | 14 ++++---- .../PrimeOrderCalculator.Wide.cs | 34 +++++++++++-------- PerfectNumbers.Core/PrimeOrderCalculator.cs | 2 +- 4 files changed, 43 insertions(+), 28 deletions(-) diff --git a/PerfectNumbers.Core/FactorEntry.cs b/PerfectNumbers.Core/FactorEntry.cs index e4ba3be..590bfbb 100644 --- a/PerfectNumbers.Core/FactorEntry.cs +++ b/PerfectNumbers.Core/FactorEntry.cs @@ -1,8 +1,19 @@ namespace PerfectNumbers.Core { - public readonly struct FactorEntry(ulong value, int exponent) - { - public readonly ulong Value = value; - public readonly int Exponent = exponent; - } + public readonly struct FactorEntry + { + public readonly ulong Value; + public readonly int Exponent = 1; + + public FactorEntry(ulong value, int exponent) + { + Value = value; + Exponent = exponent; + } + + public FactorEntry(ulong value) + { + Value = value; + } + } } \ No newline at end of file diff --git a/PerfectNumbers.Core/PartialFactorResult.cs b/PerfectNumbers.Core/PartialFactorResult.cs index dc9c1b0..bd5b713 100644 --- a/PerfectNumbers.Core/PartialFactorResult.cs +++ b/PerfectNumbers.Core/PartialFactorResult.cs @@ -5,11 +5,11 @@ namespace PerfectNumbers.Core { public sealed class PartialFactorResult { - [ThreadStatic] - private static PartialFactorResult? s_poolHead; + [ThreadStatic] + private static PartialFactorResult? s_poolHead; public FactorEntry[]? Factors; - private PartialFactorResult? _next; + private PartialFactorResult? _next; public ulong Cofactor; public bool FullyFactored; public int Count; @@ -38,8 +38,8 @@ namespace PerfectNumbers.Core return instance; } - public static readonly PartialFactorResult Empty = new PartialFactorResult - { + public static readonly PartialFactorResult Empty = new() + { Cofactor = 1UL, FullyFactored = true, }; @@ -50,13 +50,13 @@ namespace PerfectNumbers.Core if (source is null || Count == 0) { FactorEntry[] local = ArrayPool.Shared.Rent(1); - local[0] = new FactorEntry(prime, 1); + local[0] = new FactorEntry(prime); return Rent(local, 1UL, true, 1); } FactorEntry[] extended = ArrayPool.Shared.Rent(Count + 1); Array.Copy(source, 0, extended, 0, Count); - extended[Count] = new FactorEntry(prime, 1); + extended[Count] = new FactorEntry(prime); Span span = extended.AsSpan(0, Count + 1); span.Sort(static (a, b) => a.Value.CompareTo(b.Value)); return Rent(extended, 1UL, true, Count + 1); diff --git a/PerfectNumbers.Core/PrimeOrderCalculator.Wide.cs b/PerfectNumbers.Core/PrimeOrderCalculator.Wide.cs index fc06285..dee949d 100644 --- a/PerfectNumbers.Core/PrimeOrderCalculator.Wide.cs +++ b/PerfectNumbers.Core/PrimeOrderCalculator.Wide.cs @@ -1062,15 +1062,20 @@ internal static partial class PrimeOrderCalculator private readonly struct FactorEntry128 { - public FactorEntry128(UInt128 value, int exponent) - { - Value = value; - Exponent = exponent; - } + public FactorEntry128(UInt128 value) + { + Value = value; + } - public UInt128 Value { get; } + public FactorEntry128(UInt128 value, int exponent) + { + Value = value; + Exponent = exponent; + } - public int Exponent { get; } + public readonly UInt128 Value; + + public readonly int Exponent = 1; } private readonly struct PartialFactorResult128 @@ -1083,13 +1088,13 @@ internal static partial class PrimeOrderCalculator Count = count; } - public FactorEntry128[]? Factors { get; } + public readonly FactorEntry128[]? Factors; - public UInt128 Cofactor { get; } + public readonly UInt128 Cofactor; - public bool FullyFactored { get; } + public readonly bool FullyFactored; - public int Count { get; } + public readonly int Count; public static PartialFactorResult128 Empty => new(null, UInt128.One, true, 0); @@ -1097,14 +1102,13 @@ internal static partial class PrimeOrderCalculator { if (Factors is null) { - FactorEntry128[] local = new FactorEntry128[1]; - local[0] = new FactorEntry128(prime, 1); - return new PartialFactorResult128(local, UInt128.One, true, 1); + FactorEntry128[] local = [new FactorEntry128(prime)]; + return new PartialFactorResult128(local, UInt128.One, true, 1); } FactorEntry128[] extended = new FactorEntry128[Count + 1]; Array.Copy(Factors, extended, Count); - extended[Count] = new FactorEntry128(prime, 1); + extended[Count] = new FactorEntry128(prime); return new PartialFactorResult128(extended, UInt128.One, true, Count + 1); } } diff --git a/PerfectNumbers.Core/PrimeOrderCalculator.cs b/PerfectNumbers.Core/PrimeOrderCalculator.cs index 398fbc3..57006f2 100644 --- a/PerfectNumbers.Core/PrimeOrderCalculator.cs +++ b/PerfectNumbers.Core/PrimeOrderCalculator.cs @@ -248,7 +248,7 @@ internal static partial class PrimeOrderCalculator // bool isPrime = PrimeTester.IsPrimeInternal(factors.Cofactor, CancellationToken.None); if (!factors.FullyFactored && factors.Cofactor > 1UL && isPrime) { - buffer[length] = new FactorEntry(factors.Cofactor, 1); + buffer[length] = new FactorEntry(factors.Cofactor); length++; }