Skip to content

Commit

Permalink
Reduce footprint of ProbMap SearchValues
Browse files Browse the repository at this point in the history
  • Loading branch information
MihaZupan authored and build committed May 15, 2024
1 parent 5b68877 commit c29dd3e
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ namespace System.Buffers
internal sealed class ProbabilisticCharSearchValues : SearchValues<char>
{
private ProbabilisticMapState _map;
private readonly string _values;

public ProbabilisticCharSearchValues(ReadOnlySpan<char> values, int maxInclusive)
{
_values = new string(values);
_map = new ProbabilisticMapState(values, maxInclusive);
}

internal override char[] GetValues() => _values.ToCharArray();
internal override char[] GetValues() =>
_map.GetValues();

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override bool ContainsCore(char value) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ public unsafe ProbabilisticMapState(ReadOnlySpan<char>* valuesPtr)
_slowContainsValuesPtr = valuesPtr;
}

public char[] GetValues()
{
Debug.Assert(_hashEntries is not null);

var unique = new HashSet<char>(_hashEntries);
char[] values = new char[unique.Count];
unique.CopyTo(values);
return values;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool FastContains(char value)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ internal sealed class ProbabilisticWithAsciiCharSearchValues<TOptimizations> : S
private IndexOfAnyAsciiSearcher.AsciiState _asciiState;
private IndexOfAnyAsciiSearcher.AsciiState _inverseAsciiState;
private ProbabilisticMapState _map;
private readonly string _values;

public ProbabilisticWithAsciiCharSearchValues(ReadOnlySpan<char> values, int maxInclusive)
{
Expand All @@ -26,11 +25,11 @@ public ProbabilisticWithAsciiCharSearchValues(ReadOnlySpan<char> values, int max
IndexOfAnyAsciiSearcher.ComputeAsciiState(values, out _asciiState);
_inverseAsciiState = _asciiState.CreateInverse();

_values = new string(values);
_map = new ProbabilisticMapState(_values, maxInclusive);
_map = new ProbabilisticMapState(values, maxInclusive);
}

internal override char[] GetValues() => _values.ToCharArray();
internal override char[] GetValues() =>
_map.GetValues();

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override bool ContainsCore(char value) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ static bool ShouldUseProbabilisticMap(int valuesLength, int maxInclusive)

// The probabilistic map is more memory efficient for spare sets, while the bitmap is more efficient for dense sets.
int bitmapFootprintBytesEstimate = 64 + (maxInclusive / 8);
int probabilisticFootprintBytesEstimate = 128 + (valuesLength * 6);
int probabilisticFootprintBytesEstimate = 128 + (valuesLength * 4);

// The bitmap is a bit faster than the perfect hash checks employed by the probabilistic map.
// Sacrifice some memory usage for faster lookups.
Expand Down

0 comments on commit c29dd3e

Please sign in to comment.