From 85f86c6511f0249546567bf6c00f57357be97421 Mon Sep 17 00:00:00 2001 From: Aristarkh Zagorodnikov Date: Sun, 21 Sep 2025 21:25:39 +0100 Subject: [PATCH] perf: minor improvements for AddHashElement (elide extra bounds check, remove the need for IDictionary devirtualization, reduce branching graph depth), this adds about 13% on .NET 8 --- CardinalityEstimation/CardinalityEstimator.cs | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/CardinalityEstimation/CardinalityEstimator.cs b/CardinalityEstimation/CardinalityEstimator.cs index ae526c1..a4005c1 100644 --- a/CardinalityEstimation/CardinalityEstimator.cs +++ b/CardinalityEstimation/CardinalityEstimator.cs @@ -111,7 +111,7 @@ public class CardinalityEstimator : ICardinalityEstimator, ICardinalityE /// /// Lookup dictionary for the sparse representation of HLL buckets /// - private IDictionary lookupSparse; + private Dictionary lookupSparse; /// /// Max number of elements to hold in the sparse representation before switching to dense @@ -787,19 +787,24 @@ private bool AddElementHash(ulong hashCode) if (isSparse) { lookupSparse.TryGetValue(substream, out byte prevRank); - lookupSparse[substream] = Math.Max(prevRank, sigma); - changed = changed || (prevRank != sigma && lookupSparse[substream] == sigma); - if (lookupSparse.Count > sparseMaxElements) + if (sigma > prevRank) { - SwitchToDenseRepresentation(); + lookupSparse[substream] = sigma; + if (lookupSparse.Count > sparseMaxElements) + { + SwitchToDenseRepresentation(); + } changed = true; } } else { - var prevMax = lookupDense[substream]; - lookupDense[substream] = Math.Max(prevMax, sigma); - changed = changed || (prevMax != sigma && lookupDense[substream] == sigma); + ref var value = ref lookupDense[substream]; + if (sigma > value) + { + value = sigma; + changed = true; + } } return changed; }