Коллекции небольшого размера из библиотеки общих коллекций C5 сравнительно очень медленные - можно ли что-нибудь сделать?

Недавно я тестировал коллекции C5 на C #, и мне очень нравится их функциональность. Для больших коллекций производительность кажется на уровне обычных аналогов. Однако для небольших коллекций они значительно медленнее. Я подозреваю, что резкое ухудшение относительной скорости происходит из-за операций с постоянным временем, выполняемых коллекциями C5. Одна операция, о которой я знаю, - это запуск событий. Может ли это быть причиной плохой работы небольших коллекций? Можно ли это исправить, отключив некоторые функции? Вот тест производительности:

//Two containers to be tested. 'Test' is a wrapper over decimal.
var arrayList = new C5.ArrayList<Test>();
var genericList = new System.Collections.Generic.List<Test>();

var toBeAdded = new List<Test>();
var watch = new Stopwatch();

//Fill both tested containers
for (int i = 10; i > 0; i--)
{
    var test = new Test(i);
    genericList.Add(test);
    arrayList.Add(test);
}

//Fill the container the range of which will be inserted to the tested containers
for (int i = 5; i > 0; i--)
{
    toBeAdded.Add(new Test(i+0.5m));
}


//Test the speed of adding a range of values and sorting for both containers
watch.Start();
genericList.AddRange(toBeAdded);
Console.WriteLine("Adding values for generic list: {0} ticks", watch.ElapsedTicks);
watch.Restart();
genericList.Sort();
Console.WriteLine("Sorting for generic list: {0} ticks", watch.ElapsedTicks);

watch.Restart();
arrayList.AddAll(toBeAdded);
Console.WriteLine("Adding values for C5 ArrayList: {0} ticks", watch.ElapsedTicks);
watch.Restart();
arrayList.Sort();
Console.WriteLine("Sorting for C5 ArrayList: {0} ticks", watch.ElapsedTicks);

и класс Test:

class Test : IComparable
{
    private decimal _number;
    internal Test(decimal aNumber)
    {
        _number = aNumber;
    }        
    public int CompareTo(object obj)
    {
        var test = (Test) obj;
        return _number.CompareTo(test._number);
    } 
}

Результат:

Adding values for generic list: 56 ticks
Sorting for generic list: 770 ticks
Adding values for C5 ArrayList: 3575 ticks
Sorting for C5 ArrayList: 4815 ticks

И C5, и тест - это сборки Release. Соотношение скоростей примерно 60x для вставки и 6x для сортировки остается неизменным между тестовыми запусками.

РЕДАКТИРОВАТЬ: вышеуказанный тест был запущен из VS. Результатами работы за пределами VS являются:

Adding values for generic list: 54 ticks
Sorting for generic list: 2135 ticks
Adding values for C5 ArrayList: 5765 ticks
Sorting for C5 ArrayList: 5198 ticks

Опять же, соотношение скоростей примерно 100x для вставки и 2x для сортировки одинаково между тестовыми прогонами.

Мой проект включает в себя множество манипуляций с небольшими контейнерами, и их производительность имеет первостепенное значение. Контейнеры C5 обладают отличной функциональностью, и я бы хотел их использовать, но в настоящий момент не могу по соображениям производительности. Буду признателен за любое понимание по этому поводу.

EDIT2: в соответствии с ответом Iridium я выполнил тест в цикле (поместив всю логику, включая создание контейнера в цикл, чтобы исключить любые трюки оптимизации компилятора), отбросил первые два результата и усреднил последующие 1000 результатов. Они здесь:

Adding values for generic list: 1.09 ticks
Sorting for generic list: 14.07 ticks
Adding values for C5 ArrayList: 1.92 ticks
Sorting for C5 ArrayList: 13.69 ticks

Теперь вставка C5 на 76% медленнее, а сортировка такая же, как у List. Этого достаточно для моей цели. Я принимаю ответ Иридиум. Тем не менее, если у кого-то есть какие-либо сведения о более медленной установке, поделитесь, пожалуйста. Спасибо всем за помощь.


person Arbil    schedule 02.10.2012    source источник
comment
На всякий случай, вы пару раз запускаете релизную сборку вне VS и т. Д.?   -  person gjvdkamp    schedule 03.10.2012
comment
@gjvdkamp Я использую сборки Release как для теста, так и для самой библиотеки C5. Я провожу каждый тест несколько раз, и результаты стабильны. Вышеупомянутое было выполнено внутри VS; Я добавил результаты для прогона вне VS. Они немного разные, но проблема с производительностью все еще остается. Спасибо за вопрос.   -  person Arbil    schedule 03.10.2012
comment
Бегло взглянув на C5 ArrayList в декомпиляторе, я мог бы подумать, что ответ - нет, вы не можете улучшить производительность. C5 имеет более многоуровневый подход по сравнению с обычным List, и, очевидно, это имеет свою цену с точки зрения производительности.   -  person Martin Liversage    schedule 03.10.2012
comment
@MartinLiversage Это мое впечатление тоже, не без серьезной модификации C5. Жалко, кажется, мне придется расширить List ‹T› некоторыми полезными методами C5. (Если вы используете Reflector в dll, хорошо прокомментированный источник можно получить здесь) . Спасибо, что изучили это.   -  person Arbil    schedule 03.10.2012


Ответы (1)


Мне интересно, если ваши результаты немного вводят в заблуждение, и что различия, которые вы видите для C5, на самом деле (возможно) связаны с накладными расходами на загрузку сборки / JIT-компиляцию при первом использовании метода добавления / сортировки. Общие коллекции не страдают от этого в результате того, что системные сборки уже загружены / загружены.

Я повторил ваш тест, используя C5 2.1.4596.30350, но провел весь тест несколько раз (без перезапуска приложения, чтобы избежать одноразовых накладных расходов). Результаты, по-видимому, предполагают, что существует штраф по времени при первом использовании коллекций C5 (в соответствии с одноразовыми накладными расходами, такими как JIT-компиляция), который исчезает при последующем использовании, оставляя производительность C5 фактически такой же, как у общих коллекций.

График добавления и сортировки общего и C5 при повторных запусках]

person Iridium    schedule 03.10.2012
comment
Спасибо за Ваш ответ. Я получаю очень похожие результаты, и они достаточно хороши для меня, чтобы использовать C5 (трудно определить разницу между добавками в вашем тесте, потому что вы используете логарифмическую шкалу). Ради интереса, вы подключали результаты тестирования к стороннему приложению для построения графиков или используете какой-то интегрированный пакет для тестирования производительности? - person Arbil; 03.10.2012
comment
@Arbil Я настроил ваши Console.WriteLine () так, чтобы они выводили данные в формате CSV, и поместил их в Excel (2007) для создания диаграммы, ничего особенного. - person Iridium; 03.10.2012