У меня есть синтаксический анализатор csv, который читает в 15+ миллион строк (со многими дубликатами) и после разбора в структуры должен быть добавлен в коллекцию. Каждая структура имеет свойства Key (int), A (datetime) и B (int) (и другие, которые здесь не актуальны).
Требование A: коллекция должна обеспечить уникальность ключа.
Требование B: На следующем этапе мне нужна коллекция, отсортированная по свойствам A (timestamp), затем B (int).
Ограничение. Структуры в конечном итоге должны проходить по порядку поочередно со ссылками на соседей (здесь LinkedList представляет собой самое чистое решение); точкой этой операции является разбиение множества. Предположим, что это самое раннее, что может произойти разбиение (т.е. Оно не может быть разделено на этапе синтаксического анализа).
Я обнаружил, что SortedSet работает достаточно хорошо для Требования A, и он довольно эффективен, даже если вставки O (log n) намного медленнее, чем с HashSet<T>
O (1), хотя мне все равно о сортировке по ключу. HashSet<T>
становится увязшим, когда коллекция становится огромной, что, по-видимому, является известной проблемой, в то время как SortedSet<T>
не страдает этим недостатком.
Проблема. Когда я SortedSet<T>
к шагу для требования B, сортировка коллекции (SortedSet<T>
переданная методу как IEnumerable<T>
) занимает слишком много времени (20+ минут шлифования, все в памяти, отсутствие использования файла страницы).
Вопрос: Какие коллекции лучше всего подходят для решения этой проблемы? Одна идея состоит в том, чтобы использовать две коллекции: одну для обеспечения уникальности (например, HashSet<int>
или SortedSet<int>
), а вторую SortedSet<T>
- обработку сортировки на этапе синтаксического анализа (т. SortedSet<T>
Как можно дальше вверх по течению). Но приложение уже интенсивно использует память, и штрафы за производительность, требуемые для файла подкачки, являются непомерно высокими.
Какие варианты оставляют меня для одной коллекции, которая обеспечивает уникальность по одной характеристике, но сортируется по другим несвязанным характеристикам? SortedSet<T>
использует IComparer<T>
(но не оба IComparer<T>
и IEquitable<T>
), поэтому, если он полагается на CompareTo для обеспечения уникальности, то он, похоже, не соответствует моим требованиям. Подклассы SortedSet, как идти?
Изменить: код сортировки:
SortedSet<Dto> parsedSet = {stuff};
var sortedLinkedStructs = new LinkedList<Dto>(parsedSet.OrderBy(t => t.Timestamp).ThenBy(i => i.SomeInt));
Структура:
public readonly struct Dto: IEquatable<Dto>, IComparer<Dto>, IComparable<Dto>
{
public readonly datetime Timestamp;
public readonly int SomeInt;
public readonly int Key;
ctor(ts, int, key){assigned}
public bool Equals(Dtoother) => this.Key == other.Key;
public override int GetHashCode() => this.Key.GetHashCode();
public int Compare(Dto x, Dto y) => x.Key.CompareTo(y.Key);
public int CompareTo(Dto other) => this.Key.CompareTo(other.Key);
}