Я использую gc мерзавца после того, как я сделаю большой контроль и буду иметь много нового объекта. это может оставить свободное место. Например, если Вы контроль, большой проект SVN с помощью мерзавца-svn, и делает gc мерзавца, Вы обычно, оставляете много свободного места
Почему бы не измерить это:
class Program
{
class NameComparer : IComparer<string>
{
public int Compare(string x, string y)
{
return string.Compare(x, y, true);
}
}
class Person
{
public Person(string id, string name)
{
Id = id;
Name = name;
}
public string Id { get; set; }
public string Name { get; set; }
}
static void Main()
{
List<Person> persons = new List<Person>();
persons.Add(new Person("P005", "Janson"));
persons.Add(new Person("P002", "Aravind"));
persons.Add(new Person("P007", "Kazhal"));
Sort(persons);
OrderBy(persons);
const int COUNT = 1000000;
Stopwatch watch = Stopwatch.StartNew();
for (int i = 0; i < COUNT; i++)
{
Sort(persons);
}
watch.Stop();
Console.WriteLine("Sort: {0}ms", watch.ElapsedMilliseconds);
watch = Stopwatch.StartNew();
for (int i = 0; i < COUNT; i++)
{
OrderBy(persons);
}
watch.Stop();
Console.WriteLine("OrderBy: {0}ms", watch.ElapsedMilliseconds);
}
static void Sort(List<Person> list)
{
list.Sort((p1, p2) => string.Compare(p1.Name, p2.Name, true));
}
static void OrderBy(List<Person> list)
{
var result = list.OrderBy(n => n.Name, new NameComparer()).ToArray();
}
}
На моем компьютере при компиляции в режиме выпуска эта программа печатает:
Sort: 1162ms
OrderBy: 1269ms
ОБНОВЛЕНИЕ:
Как предлагает @Stefan здесь являются результатом меньшего количества сортировок большого списка:
List<Person> persons = new List<Person>();
for (int i = 0; i < 100000; i++)
{
persons.Add(new Person("P" + i.ToString(), "Janson" + i.ToString()));
}
Sort(persons);
OrderBy(persons);
const int COUNT = 30;
Stopwatch watch = Stopwatch.StartNew();
for (int i = 0; i < COUNT; i++)
{
Sort(persons);
}
watch.Stop();
Console.WriteLine("Sort: {0}ms", watch.ElapsedMilliseconds);
watch = Stopwatch.StartNew();
for (int i = 0; i < COUNT; i++)
{
OrderBy(persons);
}
watch.Stop();
Console.WriteLine("OrderBy: {0}ms", watch.ElapsedMilliseconds);
Печать:
Sort: 8965ms
OrderBy: 8460ms
В этом сценарии похоже, что OrderBy работает лучше.
UPDATE2:
И с использованием случайных имен:
List<Person> persons = new List<Person>();
for (int i = 0; i < 100000; i++)
{
persons.Add(new Person("P" + i.ToString(), RandomString(5, true)));
}
Где:
private static Random randomSeed = new Random();
public static string RandomString(int size, bool lowerCase)
{
var sb = new StringBuilder(size);
int start = (lowerCase) ? 97 : 65;
for (int i = 0; i < size; i++)
{
sb.Append((char)(26 * randomSeed.NextDouble() + start));
}
return sb.ToString();
}
Выход:
Sort: 8968ms
OrderBy: 8728ms
Still OrderBy быстрее
Нет, это разные алгоритмы. Для начала, LINQ OrderBy
задокументирован как стабильный (т. Е. Если два элемента имеют одинаковое имя
, они будут отображаться в исходном порядке).
Это также зависит от того, буферизуете ли вы запрос или повторяете его несколько раз (LINQ-to-Objects, если вы не буферизуете результат, будет переупорядочен на foreach
).
Для OrderBy
запрос, я также хотел бы использовать:
OrderBy(n => n.Name, StringComparer.{yourchoice}IgnoreCase);
(для {yourchoice}
один из CurrentCulture
, Ordinal
или InvariantCulture
).
Этот метод использует Array.Sort, который использует алгоритм QuickSort. Эта реализация работает нестабильно Сортировать; то есть, если два элемента равны, их порядок может не быть сохранились. Напротив, стабильная сортировка сохраняет порядок элементов, которые равны.
Этот метод выполняет стабильную сортировку; то есть, если ключи двух элементов равны, порядок элементов сохраняется. Напротив, нестабильная сортировка не сохраняет порядок элементов с одним и тем же ключом. Сортировать; то есть, если два элемента равны, их порядок может не быть сохранились. Напротив, стабильная сортировка сохраняет порядок элементов, которые равны.
Думаю, важно отметить еще одно различие между Sort
и OrderBy
:
Предположим, существует метод Person.CalculateSalary()
, который занимает много времени; возможно, больше, чем даже операция сортировки большого списка.
Сравнение
// Option 1
persons.Sort((p1, p2) => Compare(p1.CalculateSalary(), p2.CalculateSalary()));
// Option 2
var query = persons.OrderBy(p => p.CalculateSalary());
Вариант 2 может иметь более высокую производительность, поскольку он вызывает метод CalculateSalary
только n раз, тогда как вариант Sort
может вызвать CalculateSalary
до 2n log(n) раз, в зависимости от успешности алгоритма сортировки.