. , ; , , . , , , . , :
List<KeyType> keys = dict.Keys.OrderBy(k => k).ToList();
List<RangeType> ranges = rangeList.OrderBy(r => r.LowerBound).ToList();
var iKey = 0;
var iRange = 0;
var count = 0;
while (iKey < keys.Count && iRange < ranges.Count)
{
if (keys[iKey] < ranges[i].LowerBound)
{
++iKey;
}
else if (keys[iKey] > ranges[i].UpperBound)
{
++iRange;
}
else
{
++count;
++iKey;
}
}
while (iKey < keys.Count)
{
notFoundKeys.Add(keys[iKey]);
++iKey;
}
, .
O (n), n - .
, 100 000 , . , , . . , .
, , . - O (q log n), q - . log2 (100000) 16,6. , 1000 33 200 - , , .
:
foreach (var range in ranges)
{
int firstIndex = keys.BinarySearch(range.LowerBound);
if (firstIndex < 0) firstIndex = ~firstIndex;
int lastIndex = keys.BinarySearch(range.UpperBound);
if (lastIndex < 0) lastIndex = ~lastIndex-1;
if (keys[firstIndex] >= range.LowerBound && keys[lastIndex] <= range.UpperBound)
count += 1 + (lastIndex - firstIndex);
}
List.BinarySearch , . , , , .
, , , , . .
BinarySearch overload, . , , 0-50 27, 27 51-100 . , .
, , , , , - . , # ( List<T>.BinarySearch), , , 10 , , . , , , 5-10 . , , .
, . , . - , , , , . , , . , - 3000 , n/(2*log2(n)) 3,012.
Again, since you are talking relatively small numbers, any algorithm will most likely work well for you. If you hit this thing hundreds or thousands of times per second, then you will want to conduct a detailed analysis and perform time with representative data and a different number of ranges. If you rarely click on it, then just add something that works and worry about optimization if it becomes a performance issue.