Ускорение С#
На самом деле это два вопроса, но они настолько похожи, и чтобы все было просто, я подумал, что просто сверну их:
-
Во-первых: Учитывая установленный проект С#, каковы некоторые достойные способы ускорить его за рамки простой оптимизации в коде?
-
Во-вторых,: При написании программы с нуля на С#, какие хорошие способы значительно повысить производительность?
Пожалуйста, избегайте общих методов оптимизации, если они не являются специфическими для С#.
Ранее было предложено Python, Perl и Java.
Ответы
Ответ 1
Сверху моей головы:
- Замените не общие варианты классов контейнеров своими родовыми аналогами
- Сокращение бокса/распаковки. В частности, используйте генераторы, где это возможно, и обычно избегайте пропускать типы значений как
object
.
- Для диалогов с использованием многих динамических элементов управления: приостановите рисование до тех пор, пока не вставьте все элементы управления с помощью
SuspendLayout
/ResumeLayout
. Это особенно помогает при использовании макетов контейнеров.
Ответ 2
К сожалению, относительно небольшое количество оптимизаций зависит от языка. Основы применимы к языкам:
- Измерение производительности по сравнению с реалистичными нагрузками
- У вас четко определены цели, которые помогут вам.
- Использовать хороший профилировщик
- Оптимизировать архитектуру/дизайн относительно рано
- Только микро-оптимизация, когда у вас есть проверенная проблема.
Когда вы абсолютно доказали, что вам нужна микро-оптимизация, профайлер стремится сделать его очевидным, что искать - такие вещи, как избегать бокса и виртуальных вызовов.
О, одна вещь, о которой я могу думать, которая специфична для .NET: если вам нужно часто звонить и в настоящее время использовать отражение, конвертировать эти вызовы в делегаты.
EDIT: другие ответы, предлагающие использование дженериков и StringBuilder и т.д., конечно, правильны. Я (возможно, ошибочно) предположил, что эти оптимизации были слишком "очевидными";)
Ответ 3
Одна простая вещь - убедиться, что для вашей конфигурации сборки установлено значение "Release". Это позволит оптимизировать и исключить информацию отладки, делая ваш исполняемый файл меньше.
Подробнее в MSDN, если необходимо.
Ответ 4
Используйте качественный профилировщик и определите, где ваши узкие места.
Затем начните спрашивать, как повысить производительность.
Любой, кто делает какие-либо общие заявления, такие как "избегать отражения", не понимая как свой профиль производительности, так и ваш проблемный домен, должен быть расстрелян (или, по крайней мере, перевоспитан). И учитывая размер ландшафта .Net, довольно бессмысленно говорить о оптимизации С#: говорим ли мы о WinForms, ASP.Net, BizTalk, Workflow, SQL-CLR? Без контекста даже общие рекомендации могут быть в лучшем случае пустой тратой времени.
Рассмотрим также то, что вы подразумеваете под "ускорением" и "улучшением производительности". Вы имеете в виду большую ресурсоэффективность или более низкое воспринимаемое время ожидания для конечного пользователя (при условии, что оно есть)? Это очень разные проблемы для решения.
Учитывая форум, я чувствую себя обязанным указать, что в Code Complete есть довольно неплохой охват этих тем. Не особый ум С#. Но это хорошо. Имейте в виду, что языковые специфические микрооптимизации могут быть включены в следующую версию того компилятора, который вы используете. И если для вас важна разница между for и foreach, вы, вероятно, пишете С++ в любом случае, верно?
[Мне понравился RedGate ANTS Profiler, но я думаю, что его можно было бы улучшить]
С этим, некоторые мысли:
- Использовать тип (SomeType) в предпочтении
instance.GetType(), когда возможно
- Использование
foreach, предпочтительнее для
- Избегайте
бокс
- До (я думаю) 3 строки
это нормально, чтобы сделать StringA + StringB +
StringC. После этого вы должны использовать
StringBuilder
Ответ 5
-
Используйте StringBuilder, а не много конкатенации строк. Строковые объекты являются атомарными, и любая модификация (добавление, верхнее, заполнение и т.д.) Фактически генерирует совершенно новый строковый объект, а не модифицирует оригинал. Каждая новая строка должна быть выделена и в конечном итоге собран мусор.
-
Обобщение предыдущего утверждения: попробуйте повторно использовать объекты, а не создавать их много и много. Выделение и сбор мусора может быть легко сделать, но они поражают вашу производительность.
-
Обязательно используйте предоставленные библиотеки Microsoft для большинства вещей. В классах, предоставляемых Framework, часто используются функции, которые недоступны или труднодоступны из вашего собственного кода на С# (т.е. Совершают вызовы в родной Windows API). Встроенные библиотеки не всегда являются наиболее эффективными, но чаще всего.
-
Написание асинхронных приложений никогда не было проще. Изучите такие вещи, как класс BackgroundWorker.
-
Старайтесь не определять Структуры, если они вам действительно не нужны. Каждый экземпляр класса содержит ссылку на фактический экземпляр, в то время как переменные экземпляра структуры содержат отдельную копию.
Ответ 6
Использовать композицию вместо наследования, ограничивать бокс/распаковку, использовать общие коллекции, использовать foreach-циклы вместо {} с помощью счетчика и выделять ресурсы со стандартным шаблоном Dispose.
Они подробно описаны в превосходной книге "Эффективный С#".
Ответ 7
Профилируйте свой код. Тогда вы можете по крайней мере понять, где вы можете улучшить. Без профилирования вы стреляете в темноту...
Ответ 8
Много медленности связано с доступом к базе данных. Сделайте ваши запросы к базе данных эффективными, и вы многое сделаете для своего приложения.
Ответ 9
NGEN поможет с некоторым кодом, но не берется за него.
Лично, если ваш дизайн плох/медленный, вы не можете многое сделать.
Лучшим предложением в таком случае является реализация некоторой формы кэширования дорогостоящих задач.
Ответ 10
Я рекомендую вам эти книги:
Эффективный С#.
Более эффективный С#
Ответ 11
Не используйте много отражений.
Ответ 12
Использовать Ngen.exe(должен поставляться с Visual Studio.)
http://msdn.microsoft.com/en-us/library/6t9t5wcf(VS.80).aspx
Генератор собственных изображений (Ngen.exe) - это инструмент, который улучшает производительность управляемых приложений. Ngen.exe создает собственные образы, которые представляют собой файлы, содержащие скомпилированный процессорный код для конкретного процессора, и устанавливает их в собственный кеш образа на локальном компьютере. Среда выполнения может использовать собственные изображения из кэша вместо использования компилятора "точно в срок" (JIT) для компиляции исходной сборки.
Ответ 13
В дополнение к перечисленным выше передовым методам кодирования, включая использование StringBuilders, когда это необходимо, и элементы такого характера.
Я настоятельно рекомендую использовать инструмент профилирования кода, например ANTs Profiler by RedGate. Я обнаружил, что после принятия стандартных шагов для оптимизации, которые используют Profiler, я могу еще больше оптимизировать свой код, быстро идентифицируя области (области) кода, которые наиболее сильно пострадали от приложения.
Ответ 14
Это верно для любого языка, а не только С#
-
Для существующего приложения ничего не делайте, пока не узнаете, что делает его медленным. IMHO, это лучший способ.
-
Для новых приложений проблема заключается в том, как преподаются программисты. Их учат делать горы из мухи. После того, как вы оптимизировали несколько приложений, используя this, вы будете знакомы с проблемой того, что я называю "галопирующей общностью" - слой за слоем "абстракция", а не просто спрашивать, что требует эта проблема. Лучшее, на что вы можете надеяться, - бежать за ними, рассказывая им, какие проблемы с производительностью они только что вложили, чтобы они могли вытащить их, когда они идут.
Ответ 15
У меня есть следующая статья в MSDN, и я считаю, что это хорошая общая ссылка.
Улучшение производительности приложений .NET
Ответ 16
Кэширование элементов, которые являются результатом запроса:
private Item _myResult;
public Item Result
{
get
{
if (_myResult == null)
{
_myResult = Database.DoQueryForResult();
}
return _myResult;
}
}
Это базовый метод, который часто игнорируется при запуске программистов, и один из способов EASIEST для повышения производительности в приложении.
Ответ перенесен из вопроса, который был признан ошибкой этого.
Ответ 17
Для Windows Forms в XP и Vista: поверните двойную буферизацию по всей доске. Это вызывает проблемы с прозрачностью, поэтому вы обязательно захотите проверить пользовательский интерфейс:
protected override System.Windows.Forms.CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle = cp.ExStyle | 0x2000000;
return cp;
}
}