perf: Optimize non-prefix key strategies and
memory usage - Conditionally allocate prefix buffers in `LeafNode` and introduce `PrefixInternalNode` to reduce memory overhead when prefixes are disabled. - Bypass prefix calculation and logic entirely when `UsesPrefixes` is false. - Add a binary search fallback for key scanning. - Implement a dedicated `int` scanning fast-path, removing SIMD prefix usage from `IntStrategy`. - Reorganize key strategies into separate files. - Add a new benchmark project specifically for string keys.
This commit is contained in:
parent
570a736606
commit
9242c1c751
13 changed files with 1297 additions and 677 deletions
|
|
@ -1,3 +1,5 @@
|
|||
namespace PersistentMap;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
public struct DoubleStrategy : IKeyStrategy<double>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
namespace PersistentMap;
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
public struct IntStrategy : IKeyStrategy<int>
|
||||
{
|
||||
public bool UsesPrefixes => false;
|
||||
public bool IsLossless => true;
|
||||
public bool UseBinarySearch => false;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int Compare(int x, int y) => x.CompareTo(y);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public long GetPrefix(int key) => 0; // Unused
|
||||
}
|
||||
|
|
@ -1,3 +1,9 @@
|
|||
namespace PersistentMap;
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86; // For AVX2
|
||||
using System.Numerics;
|
||||
/// <summary>
|
||||
/// Helper for SIMD accelerated prefix scanning.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
namespace PersistentMap;
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
/// <summary>
|
||||
/// A universal key strategy for any type that relies on standard comparisons
|
||||
/// (IComparable, IComparer, or custom StringComparers) without SIMD prefixes.
|
||||
|
|
@ -9,11 +11,16 @@ public readonly struct StandardStrategy<K> : IKeyStrategy<K>
|
|||
|
||||
// If no comparer is provided, it defaults to Comparer<K>.Default
|
||||
// which automatically uses IComparable<K> if the type implements it.
|
||||
public StandardStrategy(IComparer<K>? comparer = null)
|
||||
|
||||
public StandardStrategy()
|
||||
{
|
||||
_comparer = Comparer<K>.Default;
|
||||
}
|
||||
|
||||
public StandardStrategy(IComparer<K>? comparer)
|
||||
{
|
||||
_comparer = comparer ?? Comparer<K>.Default;
|
||||
}
|
||||
|
||||
// Tell the B-Tree to skip SIMD routing and just use LinearSearch
|
||||
public bool UsesPrefixes => false;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue