Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 39a44df

Browse files
committed
Colocate length filter calculations to avoid repeat enumeration
1 parent 641929e commit 39a44df

File tree

3 files changed

+31
-35
lines changed

3 files changed

+31
-35
lines changed

src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenDictionary.cs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,12 @@ private static FrozenDictionary<TKey, TValue> CreateFromDictionary<TKey, TValue>
161161

162162
// Calculate the minimum and maximum lengths of the strings in the dictionary. Several of the analyses need this.
163163
int minLength = int.MaxValue, maxLength = 0;
164+
ulong lengthFilter = 0;
164165
foreach (string key in keys)
165166
{
166167
if (key.Length < minLength) minLength = key.Length;
167168
if (key.Length > maxLength) maxLength = key.Length;
169+
lengthFilter |= (1UL << (key.Length % 64));
168170
}
169171
Debug.Assert(minLength >= 0 && maxLength >= minLength);
170172

@@ -184,29 +186,29 @@ private static FrozenDictionary<TKey, TValue> CreateFromDictionary<TKey, TValue>
184186
if (analysis.IgnoreCase)
185187
{
186188
frozenDictionary = analysis.AllAsciiIfIgnoreCase
187-
? new OrdinalStringFrozenDictionary_RightJustifiedCaseInsensitiveAsciiSubstring<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex, analysis.HashCount)
188-
: new OrdinalStringFrozenDictionary_RightJustifiedCaseInsensitiveSubstring<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex, analysis.HashCount);
189+
? new OrdinalStringFrozenDictionary_RightJustifiedCaseInsensitiveAsciiSubstring<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex, analysis.HashCount)
190+
: new OrdinalStringFrozenDictionary_RightJustifiedCaseInsensitiveSubstring<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex, analysis.HashCount);
189191
}
190192
else
191193
{
192194
frozenDictionary = analysis.HashCount == 1
193-
? new OrdinalStringFrozenDictionary_RightJustifiedSingleChar<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex)
194-
: new OrdinalStringFrozenDictionary_RightJustifiedSubstring<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex, analysis.HashCount);
195+
? new OrdinalStringFrozenDictionary_RightJustifiedSingleChar<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex)
196+
: new OrdinalStringFrozenDictionary_RightJustifiedSubstring<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex, analysis.HashCount);
195197
}
196198
}
197199
else
198200
{
199201
if (analysis.IgnoreCase)
200202
{
201203
frozenDictionary = analysis.AllAsciiIfIgnoreCase
202-
? new OrdinalStringFrozenDictionary_LeftJustifiedCaseInsensitiveAsciiSubstring<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex, analysis.HashCount)
203-
: new OrdinalStringFrozenDictionary_LeftJustifiedCaseInsensitiveSubstring<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex, analysis.HashCount);
204+
? new OrdinalStringFrozenDictionary_LeftJustifiedCaseInsensitiveAsciiSubstring<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex, analysis.HashCount)
205+
: new OrdinalStringFrozenDictionary_LeftJustifiedCaseInsensitiveSubstring<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex, analysis.HashCount);
204206
}
205207
else
206208
{
207209
frozenDictionary = analysis.HashCount == 1
208-
? new OrdinalStringFrozenDictionary_LeftJustifiedSingleChar<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex)
209-
: new OrdinalStringFrozenDictionary_LeftJustifiedSubstring<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex, analysis.HashCount);
210+
? new OrdinalStringFrozenDictionary_LeftJustifiedSingleChar<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex)
211+
: new OrdinalStringFrozenDictionary_LeftJustifiedSubstring<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex, analysis.HashCount);
210212
}
211213
}
212214
}
@@ -215,12 +217,12 @@ private static FrozenDictionary<TKey, TValue> CreateFromDictionary<TKey, TValue>
215217
if (analysis.IgnoreCase)
216218
{
217219
frozenDictionary = analysis.AllAsciiIfIgnoreCase
218-
? new OrdinalStringFrozenDictionary_FullCaseInsensitiveAscii<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter)
219-
: new OrdinalStringFrozenDictionary_FullCaseInsensitive<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter);
220+
? new OrdinalStringFrozenDictionary_FullCaseInsensitiveAscii<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter)
221+
: new OrdinalStringFrozenDictionary_FullCaseInsensitive<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter);
220222
}
221223
else
222224
{
223-
frozenDictionary = new OrdinalStringFrozenDictionary_Full<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter);
225+
frozenDictionary = new OrdinalStringFrozenDictionary_Full<TValue>(keys, values, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter);
224226
}
225227
}
226228

src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/FrozenSet.cs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,12 @@ private static FrozenSet<T> CreateFromSet<T>(HashSet<T> source)
109109

110110
// Calculate the minimum and maximum lengths of the strings in the set. Several of the analyses need this.
111111
int minLength = int.MaxValue, maxLength = 0;
112-
foreach (string s in entries)
112+
ulong lengthFilter = 0;
113+
foreach (string key in entries)
113114
{
114-
if (s.Length < minLength) minLength = s.Length;
115-
if (s.Length > maxLength) maxLength = s.Length;
115+
if (key.Length < minLength) minLength = key.Length;
116+
if (key.Length > maxLength) maxLength = key.Length;
117+
lengthFilter |= (1UL << (key.Length % 64));
116118
}
117119
Debug.Assert(minLength >= 0 && maxLength >= minLength);
118120

@@ -132,29 +134,29 @@ private static FrozenSet<T> CreateFromSet<T>(HashSet<T> source)
132134
if (analysis.IgnoreCase)
133135
{
134136
frozenSet = analysis.AllAsciiIfIgnoreCase
135-
? new OrdinalStringFrozenSet_RightJustifiedCaseInsensitiveAsciiSubstring(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex, analysis.HashCount)
136-
: new OrdinalStringFrozenSet_RightJustifiedCaseInsensitiveSubstring(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex, analysis.HashCount);
137+
? new OrdinalStringFrozenSet_RightJustifiedCaseInsensitiveAsciiSubstring(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex, analysis.HashCount)
138+
: new OrdinalStringFrozenSet_RightJustifiedCaseInsensitiveSubstring(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex, analysis.HashCount);
137139
}
138140
else
139141
{
140142
frozenSet = analysis.HashCount == 1
141-
? new OrdinalStringFrozenSet_RightJustifiedSingleChar(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex)
142-
: new OrdinalStringFrozenSet_RightJustifiedSubstring(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex, analysis.HashCount);
143+
? new OrdinalStringFrozenSet_RightJustifiedSingleChar(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex)
144+
: new OrdinalStringFrozenSet_RightJustifiedSubstring(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex, analysis.HashCount);
143145
}
144146
}
145147
else
146148
{
147149
if (analysis.IgnoreCase)
148150
{
149151
frozenSet = analysis.AllAsciiIfIgnoreCase
150-
? new OrdinalStringFrozenSet_LeftJustifiedCaseInsensitiveAsciiSubstring(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex, analysis.HashCount)
151-
: new OrdinalStringFrozenSet_LeftJustifiedCaseInsensitiveSubstring(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex, analysis.HashCount);
152+
? new OrdinalStringFrozenSet_LeftJustifiedCaseInsensitiveAsciiSubstring(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex, analysis.HashCount)
153+
: new OrdinalStringFrozenSet_LeftJustifiedCaseInsensitiveSubstring(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex, analysis.HashCount);
152154
}
153155
else
154156
{
155157
frozenSet = analysis.HashCount == 1
156-
? new OrdinalStringFrozenSet_LeftJustifiedSingleChar(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex)
157-
: new OrdinalStringFrozenSet_LeftJustifiedSubstring(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter, analysis.HashIndex, analysis.HashCount);
158+
? new OrdinalStringFrozenSet_LeftJustifiedSingleChar(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex)
159+
: new OrdinalStringFrozenSet_LeftJustifiedSubstring(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter, analysis.HashIndex, analysis.HashCount);
158160
}
159161
}
160162
}
@@ -163,12 +165,12 @@ private static FrozenSet<T> CreateFromSet<T>(HashSet<T> source)
163165
if (analysis.IgnoreCase)
164166
{
165167
frozenSet = analysis.AllAsciiIfIgnoreCase
166-
? new OrdinalStringFrozenSet_FullCaseInsensitiveAscii(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter)
167-
: new OrdinalStringFrozenSet_FullCaseInsensitive(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter);
168+
? new OrdinalStringFrozenSet_FullCaseInsensitiveAscii(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter)
169+
: new OrdinalStringFrozenSet_FullCaseInsensitive(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter);
168170
}
169171
else
170172
{
171-
frozenSet = new OrdinalStringFrozenSet_Full(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, analysis.LengthFilter);
173+
frozenSet = new OrdinalStringFrozenSet_Full(entries, stringComparer, analysis.MinimumLength, analysis.MaximumLengthDiff, lengthFilter);
172174
}
173175
}
174176

src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/KeyAnalyzer.cs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,8 @@ private static AnalysisResults CreateAnalysisResults(
159159
}
160160
}
161161

162-
ulong lengthFilter = 0;
163-
foreach (string s in uniqueStrings)
164-
{
165-
lengthFilter |= (1UL << (s.Length % 64));
166-
}
167-
168162
// Return the analysis results.
169-
return new AnalysisResults(ignoreCase, allAsciiIfIgnoreCase, index, count, minLength, maxLength, lengthFilter);
163+
return new AnalysisResults(ignoreCase, allAsciiIfIgnoreCase, index, count, minLength, maxLength);
170164
}
171165

172166
private delegate ReadOnlySpan<char> GetSpan(string s, int index, int count);
@@ -249,15 +243,14 @@ internal static bool HasSufficientUniquenessFactor(HashSet<string> set, ReadOnly
249243

250244
internal readonly struct AnalysisResults
251245
{
252-
public AnalysisResults(bool ignoreCase, bool allAsciiIfIgnoreCase, int hashIndex, int hashCount, int minLength, int maxLength, ulong lengthFilter)
246+
public AnalysisResults(bool ignoreCase, bool allAsciiIfIgnoreCase, int hashIndex, int hashCount, int minLength, int maxLength)
253247
{
254248
IgnoreCase = ignoreCase;
255249
AllAsciiIfIgnoreCase = allAsciiIfIgnoreCase;
256250
HashIndex = hashIndex;
257251
HashCount = hashCount;
258252
MinimumLength = minLength;
259253
MaximumLengthDiff = maxLength - minLength;
260-
LengthFilter = lengthFilter;
261254
}
262255

263256
public bool IgnoreCase { get; }
@@ -266,7 +259,6 @@ public AnalysisResults(bool ignoreCase, bool allAsciiIfIgnoreCase, int hashIndex
266259
public int HashCount { get; }
267260
public int MinimumLength { get; }
268261
public int MaximumLengthDiff { get; }
269-
public ulong LengthFilter { get; }
270262

271263
public bool SubstringHashing => HashCount != 0;
272264
public bool RightJustifiedSubstring => HashIndex < 0;

0 commit comments

Comments
 (0)