C# более быстрая сортировка, чем SortedList
у нас есть
SortedList<Resource, Resource> resources =
new SortedList<Resource, Resource>(new ResourceIdle());
что мы используем в нашей модели. Этот список ресурсов инициализируется таким образом, потому что мы хотим передать разные компараторы в любой момент времени. Первая проблема у нас есть, что SortedList<>
требует дополнительного сравнения в компараторе, чтобы мы могли добавлять разные экземпляры Resource
С теми же свойствами. Например, если компаратор выглядит так:
public int Compare(Resource x, Resource y)
{
int priority1 = x.Priority;
int priority2 = y.Priority;
if (priority1 > priority2) {
return -1;
} else if (priority1 < priority2) {
return 1;
} else {
return (x.Id.CompareTo(y.Id));
}
}
тогда мы должны сделать дополнительное сравнение, когда приоритеты то же самое, иначе мы получим исключение для записи с тем же ключом. Поэтому мой вопрос в том, есть ли другой способ достичь этого? И как вторичный вопрос, есть ли что-нибудь быстрее, чем SortedList<>
для заказа большого количества объектов?
5 ответов
Ну SortedDictionary<,>
и разные ТТХ - это зависит от того, что вы делаете с ним. В MSDN достаточно подробно сравнении двух:
на
SortedDictionary<TKey, TValue>
generic class-это двоичное дерево поиска с извлечением O(log n), где n-количество элементов в словаре. В этом отношении он похож наSortedList<TKey, TValue>
универсальный класс. Два класса имеют аналогичные объектные модели, и оба имеют o(log n) извлечение. Где два класса отличаются в использовании памяти и скорости вставки и удаления:
SortedList<TKey, TValue>
использует меньше памяти, чемSortedDictionary<TKey, TValue>
.SortedDictionary<TKey, TValue>
имеет более быстрые операции вставки и удаления для несортированных данных: O(log n) в отличие от O(n) дляSortedList<TKey, TValue>
.- если список заполняется все сразу из отсортированных данных,
SortedList<TKey, TValue>
быстрееSortedDictionary<TKey, TValue>
.
это требование, чтобы список всегда сортировался в любое время? если нет, то было бы определенно быстрее сортировать только по требованию. другая идея заключается в том, чтобы сортировка выполнялась "OrderPriority", которая представляет собой комбинацию полей приоритета и ID, поэтому необходимо сделать только одно сравнение:
int OrderPriority { get { return Priority * MAX_ID + ID; } }
это предполагает, что идентификаторы не становятся слишком большими...
вы можете немного сократить сравнение:
public int Compare(Resource x, Resource y)
{
int priority1 = x.Priority;
int priority2 = y.Priority;
if (priority1 != priority2)
return priority2 - priority1;
return (x.Id.CompareTo(y.Id));
}
Если вы не заботитесь о различении между объектами с одинаковым приоритетом, почему бы не использовать SortedList ведер (возможно, реализованный как очередь), со всеми элементами равного приоритета в одном ведре?
при создании SortedList
из словаря он скопирует ключи и значения в массивы, а затем использует Array.Sort
метод сортировки, так что это почти так же быстро, как вы получаете, если у вас нет специальных знаний о коллекции, которые могли бы помочь вам выбрать другой алгоритм, который лучше подходит для этого особого случая.
однако, похоже, вы создаете словарь с тем же ключом и значением, чтобы иметь возможность использовать SortedList
. Если это в случае, вы должны просто поместить элементы в массив или список и отсортировать их. The Array.Sort
и List<T>.Sort
методы также могут использовать пользовательский компаратор.
вы comparer с вторичным сравнением можно упростить как:
public int Compare(Resource x, Resource y) {
int result = x.Priority.CompareTo(y.Priority);
if (result == 0) {
result = x.Id.CompareTo(y.Id);
}
return result;
}