понедельник, 7 июля 2014 г.

Как писать код на C # для достижения оптимальной производительности.


Заметки о том, как писать код на C # для достижения оптимальной производительности.


Термин производительность в целом относится к скорости выполнения программы. Иногда вы можете увеличить скорость выполнения, следуя определенным правилам написания исходного кода. В некоторых случаях, следует использовать профайлеры и метрики, чтобы убедиться в том, что приложение работает так быстро, как это возможно. В других, вам не придется выполнять такую ​​оптимизацию, так как приложение и так работает приемлемо быстро.
При измерении и оптимизации производительности, желательно следовать таким общим принципам:
- Начните с определения целей по производительности и измерения эффективности программы, чтобы в последующем иметь возможность определить, когда и где ваш код или его часть не удовлетворяет поставленным целям.
- Пишите свой ​​код изначально правильно, следуя общепринятым принципам проектирования, используя coding стандарты принятые на вашем проекте или организации.
- Оптимизируйте код позже, но только если вы определили, что он не способствует достижению поставленных целей по производительности. Код, который оптимизирован для выполнения часто более трудно читать и поддерживать. Как правило, лучше написать код, который читается, надежной и обслуживании, даже если это немного медленнее, чем самый оптимизированный код, что вы могли бы написать.
- Если вы должны оптимизировать, начните с самых медленных частей программы. Если выяснится, что программа не отвечает требованиям производительности, определите конкретные места, где производительность может быть улучшена, и какие вопросы производительности являются основными причинами этой проблемы. Как правило, не имеет смысла оптимизировать метод, который вызывается редко (лучше потратить время на более весомые задачи).

Рекомендации Microsoft

Рекомендации Microsoft, о том, как построить .NET приложения, которые отвечают требованиям производительности. Руководящие принципы относится к различным ролям, участвующих в SDLC, в том числе архитекторов, дизайнеров, разработчиков, тестировщиков и администраторов. Ниже приведена диаграмма.

Несколько основных советов/рекомендаций специфических для С#

Есть много различных «особенностей» которым те или иные источники советуют следовать. Я приведу несколько самых простых и базовых примеров (их в общем то действительно не много).

Boxing и Unboxing

Данные операции являются вычислительно дорогими процессами. Применительно к value типам, данные операции предусматривают перемещение значения из стека (stack) в управляемую кучу (managed heap) и обратно. Это может дать замедление до 20 раз.



Подробнее можно почитать тут.

Strings – работа с большими строками

При необходимости работы с большими строками следует предпочитать StringBuilder Class использованию оператора «+». Подробнее можно почитать тут.

Destructors

Следует избегать объявления пустых destructor-ов. Это приводит к неоправданному использования ресурсов и понижению производительности.

Design with ValueTypes

По возможности используйте простые типы и структуры (struct) где это возможно. Операции со стеком (stack) быстрее чем операции с кучей (managed heap). Сравнение.

Цикл for быстрее чем foreach

Если это возможно предпочитайте использование цикла for вместо foreach.

Генерация исключений

Генерируйте как можно меньше исключений (throw new Exception(); или throw;). Операция весьма дорогостоящая и если это возможно, то не стоит часто ее использовать.

«Спасибо Кеп»

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

Заключение

На производительность в целом больше влияют архитектурные моменты чем особенности языка программирования J

Полезные ссылки

http://msdn.microsoft.com/en-us/library/ms973839.aspx

http://en.wikipedia.org/wiki/Gang_of_Four_(band)

http://msdn.microsoft.com/en-us/library/ff649152.aspx

2 комментария:

  1. Щодо Design with ValueTypes
    Можна користуватись правилами описаними тут: http://msdn.microsoft.com/en-us/library/ms229017(v=vs.110).aspx

    Щодо циклів, варто переглянути бенчмарки, та згадати тонкості використання того чи іншого циклу:
    http://www.codeproject.com/Tips/531893/For-Vs-Foreach-Benchmark
    http://www.dotnetperls.com/for-foreach

    ОтветитьУдалить
  2. Касательно использования structure vs objects, На сколько я помню то использовать структуры целесобразно если из размер не превышает 16байт, вспомню где читал и скину ссылку.

    ОтветитьУдалить