Если вы реализуете Dictionary
, который можно увеличивать (эмулируя мультимножество или пакет), то вы можете увеличить скорость примерно в 3 раза быстрее, чем LINQ, но разница невелика, если у вас не много ngrms
. В списке из 10 миллионов, содержащем около 100 уникальных значений, код LINQ все еще занимает меньше секунды на моем ПК. Если ваш код LINQ занимает время 1, foreach
с Dictionary<string,int>
- 0,85, а этот код - 0,32.
Вот класс для создания обновляемого значения в Dictionary
:
public class Ref<T> {
public T val { get; set; }
public Ref(T firstVal) => val = firstVal;
public static implicit operator T(Ref<T> rt) => rt.val;
}
(Если бы C # позволял operator ref T
, вы могли бы вернуть ref
свойству val
и почти обработать Ref<T>
, как если бы это было lvalue типа T
.)
Теперь вы можете сосчитать вхождения строк в Dictionary<string,Ref<int>>
только с одним поиском на строку:
var dictCounts = new Dictionary<string, Ref<int>>();
foreach (var s in ngrms) {
if (dictCounts.TryGetValue(s, out var refn))
++refn.val;
else
dictCounts.Add(s, new Ref<int>(1));
}
Наконец, вы можете вычислить ответ, отфильтровав значения, которые вы хотите сохранить:
var ans = dictCounts.Where(kvp => kvp.Value > minCount).ToDictionary(kvp => kvp.Key, kvp => kvp.Value.val);