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;
}