Вид C# и сравнение OrderBy

Я использую gc мерзавца после того, как я сделаю большой контроль и буду иметь много нового объекта. это может оставить свободное место. Например, если Вы контроль, большой проект SVN с помощью мерзавца-svn, и делает gc мерзавца, Вы обычно, оставляете много свободного места

98
задан abatishchev 15 August 2011 в 16:02
поделиться

3 ответа

Почему бы не измерить это:

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 быстрее

88
ответ дан 24 November 2019 в 05:09
поделиться

Нет, это разные алгоритмы. Для начала, LINQ OrderBy задокументирован как стабильный (т. Е. Если два элемента имеют одинаковое имя , они будут отображаться в исходном порядке).

Это также зависит от того, буферизуете ли вы запрос или повторяете его несколько раз (LINQ-to-Objects, если вы не буферизуете результат, будет переупорядочен на foreach ).

Для OrderBy запрос, я также хотел бы использовать:

OrderBy(n => n.Name, StringComparer.{yourchoice}IgnoreCase);

(для {yourchoice} один из CurrentCulture , Ordinal или InvariantCulture ).

List .Sort

Этот метод использует Array.Sort, который использует алгоритм QuickSort. Эта реализация работает нестабильно Сортировать; то есть, если два элемента равны, их порядок может не быть сохранились. Напротив, стабильная сортировка сохраняет порядок элементов, которые равны.

Enumerable.OrderBy

Этот метод выполняет стабильную сортировку; то есть, если ключи двух элементов равны, порядок элементов сохраняется. Напротив, нестабильная сортировка не сохраняет порядок элементов с одним и тем же ключом. Сортировать; то есть, если два элемента равны, их порядок может не быть сохранились. Напротив, стабильная сортировка сохраняет порядок элементов, которые равны.

120
ответ дан 24 November 2019 в 05:09
поделиться

Думаю, важно отметить еще одно различие между 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) раз, в зависимости от успешности алгоритма сортировки.

35
ответ дан 24 November 2019 в 05:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: