Есть ли способ измерить штрафы за бокс / распаковку? - PullRequest
4 голосов
/ 11 ноября 2010

Я работаю с фреймворком, который использует коллекции, полученные из System.Collections.CollectionBase. Пользователи жалуются на производительность, и я чувствую, что эти коллекции, которые используются очень интенсивно, могут быть большой частью проблемы. Есть ли способ с помощью инструмента или профилировщика или в IL, чтобы я мог получить некоторые показатели по штрафам за бокс / распаковку? Мне нужны доказательства, чтобы поддержать толчок для System.Collections.Generic. Я пробовал CLRProfiler, но, как правило, заблудился и не уверен, что мне следует искать.

UPDATE
Спасибо всем за ваш вклад до сих пор. Я знаю, что это, вероятно, не является основным узким местом, но я ищу метрики для как можно большего количества возможных убийц производительности. Это только один из них, не уверен, насколько он велик, поэтому ищет способ его измерить.

Ответы [ 4 ]

10 голосов
/ 11 ноября 2010

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

Другими словами: весьма сомнительно, что boxing вызовет проблему производительности, котораяВаши пользователи заметят.

Очевидно, я говорю в обобщениях.Не зная вашего конкретного сценария, я не могу с уверенностью сказать так много.


Редактировать : Обратите внимание, что, хотя я скептически отношусь к вашей проблеме, вы можете использовать неуниверсальные коллекции как таковые, я укажу, что * очень важно, какой тип коллекции вы используете для решения данной проблемы, особенно когда объем данныхв коллекции большая.Вот лишь несколько примеров:

  • Если вы выполняете поиск на основе ключа, хеш-таблица, такая как Dictionary<TKey, TValue>, будет значительно опережать, например, List<T>.
  • Если вы проверяете наличие дубликатов, HashSet<T> будет иметь превосходную производительность.
  • Если вы ищете поведение FIFO (как в очереди), a Queue<T> будет иметь превосходную производительность.
  • Если вы выполняете вставку / удаление в произвольных позициях в коллекции, LinkedList<T> будет иметь превосходную производительность.

Эти коллекции должны быть частьюлюбого набора инструментов разработчика .NET (на самом деле, любого разработчика).Если вы обнаружите, что везде используете коллекции элементов List<T> (или ArrayList) или аналогичную структуру данных, это очень хорошо может вызвать проблемы с производительностью в будущем - опять же, особенно когда вашКоллекции большие.Это не тривиальное повышение производительности, о котором я говорю.Поэтому позаботьтесь о том, чтобы сделать разумный выбор для вашей коллекции типов .


Но я бы рекомендовал общий профилировщик производительности, например ANTS (хорошо, но не бесплатно) или EQATEC (также хорошо и бесплатно).Просто запустите ваше приложение под одной из таких программ и посмотрите, где ваши узкие места.Я предполагаю, что вы найдете это не с вашими неуниверсальными коллекциями;но, естественно, я могу ошибаться.

2 голосов
/ 11 ноября 2010

Почему бы просто не настроить быстрое консольное приложение для измерения скорости различных операций. Вы можете использовать простой метод, подобный этому:

private TimeSpan TimedAction(Action action)
{
    var timer = new Stopwatch();

    timer.Start();

    action.Invoke();

    timer.Stop();

    return timer.Elapsed;
}

И назовите это так:

var elapsed = TimedAction(() =>
    {
        //Do some stuff with your collection here
    });

Console.WriteLine("Elapsed Time: {0}", elapsed.TotalMilliseconds);

Вы должны быть в состоянии собрать достаточно эмпирических данных, чтобы выяснить, какой сбор будет быстрее при аналогичных операциях. Количество предметов, количество выполненных смежных операций и т.д ...

Однако , как Дан , упомянутый выше; общий объем производительности, потраченной на стороннюю коллекцию, вероятно, незначителен, если сопоставить доступ к данным и задержку в сети.

1 голос
/ 12 ноября 2010

@ Замечания Дана Тао прямо на деньги.

В подобных обстоятельствах я часто делаю эту технику , которую вы можете выполнять в любой среде IDE.

Итак, я знаю, что вы хотите измерить определенную вещь, но в целом ваша большая проблема - найти проблемы с производительностью, где бы они ни были, верно?

У нас есть споры о подобных проблемах, но то, на что программа действительно тратит время, не имеет к этому никакого отношения. Такие вещи, как проникновение на 30 уровней в подземные библиотеки, просто для того, чтобы извлекать строки из ресурсов, чтобы их можно было переводить на разные языки, тогда как в действительности это не нужно. Такие вещи, как кто-то, устанавливают для свойства значение True, которое устанавливает цепочку уведомлений с добавлением или удалением элементов из списков, обновлением элементов управления в виде дерева, созданием и уничтожением окон, добавлением / удалением вкладок и элементов меню и т. Д. Через некоторое время свойство снова устанавливается в False, как будто это не имеет большого значения. Такие вещи, как установка ячеек в элементе управления сеткой, где следует аналогичная приливная волна разветвлений. Как правило, хвосты виляют собаками.

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

1 голос
/ 11 ноября 2010

Вот доказательство, которое вам нужно.

С MSDN :

В дополнение к безопасности типов, универсальный Типы коллекций обычно выполняют лучше для хранения и манипулирования типы значений, потому что нет необходимости упаковывать типы значений.

Обратите внимание, что в действительности дженерики на самом деле не так быстры, как говорят Microsoft Разница незначительная.

...