Kranonit S18 Chernomorov Vasiliy "Как создать игру и не сойти с ума "
05 net saturday vasiliy borovyak ''.net performance nontrivial bottlenecks''
-
Upload
dneprciklumevents -
Category
Documents
-
view
366 -
download
1
Transcript of 05 net saturday vasiliy borovyak ''.net performance nontrivial bottlenecks''
Язык программирования OBERON
И его превосходство над другими жалкими языками программирования.
Нетривиальные ботлнеки
Как искать и находить проблемы спамятью и производительностью
в высоконагруженных .Net приложениях,которые уже якобы до конца
оптимизированны.
О самых распространённых, но скрытых проблемах.
Об оптимизации уже существующих приложений. Тривиальные проблемы. Нетривиальные проблемы.
О том, как быстро найти тормозное место. И о всяком другом помаленьку...
О чём это всё?
Вася NeuString Пишем софт для операторов сотовой
связи
Обо мне
Кто хоть иногда чинит скорость работы кода?
Кто хоть иногда чинит количество занимаемой памяти?
О вас
Обсудим как улучшать существующее, а не о том как надо правильно разрабатывать новое.
Внутренние тормоза DB/SQL или Apache/IIS здесь разбираться не будут. Это архитектурные проблемы, а не кодерские.
О презентации
Узкое место Проблема Oптимизация ... спрашивайте меня, будем
определяться по ходу.
Определимся с терминами
Частые обращения к вычисляемым данным Один поток Долгоиграющая операция не зависящая от
нас Медленный SQL скрипт Прокси/очередь сообщений Много итераций/выделений памяти Бесполезное исполнение кода/выделение
памяти Медленный алгоритм
Банальные ботлнеки
Нетривиальный ботлнек №1
Сохранение данных в хранилище (файл) длилось 2-3 минуты.
Размер файла был огромен – гигабайты.
Чтение, соответственно, тоже самое.
Во время сохранения выделялось огромное количество памяти.
Результат бинарной сериализации
BinarySerializer ~ 20 записей New serializer ~ 200 записей
Решение: рукописная сериализация.
Вывод: бинарная сериализация в .Net –
Нетривиальный ботлнек №1
Сохранение данных в хранилище (файл) длилось 2-3 минуты.
Размер файла был огромен – гигабайты.
Чтение, соответственно, тоже самое.
Во время сохранения выделялось огромное количество памяти.
Решение: найти повисший указатель.
Нетривиальный ботлнек №2
Почему-то память не высвобождалась.
public class ItemClass { public event Action Edited; } //----------------------------------------------------// public class MyHugeClass { public List<ItemClass> Items { get; private set; }
public bool Changed { get; private set; }
public void SetItems(IEnumerable<ItemClass> items) { this.Items = items.ToList(); foreach (var item in this.Items) { item.Edited += this.item_Edited; } }
public void item_Edited() { this.Changed = true; } }
public class MyHugeClass
Связь объектов
ItemClass
Delegate
Auto-generated class
MyHugeClass
Решение: найти повисший указатель.
Вывод: static –
Нетривиальный ботлнек №2
Почему-то память не высвобождалась.
Решение: создать единое универсальное хранилище информации.
Вывод: не храните дважды одно и тоже. Доступ к данным можно всегда ускорить.
Нетривиальный ботлнек №3
Приложение занимало много памяти.
Хранение одной и той же информации в двух разных видах.
Это делалось для быстрого поиска необходимого.
Решение: вычислять только необходимое.
Нетривиальный ботлнек №4 Вычислялись цифры,
которые впоследствии никуда не выводились.
Тупой примеризлишних вычислений
public class OneResult { public int Id { get; set; } public string A { get; set; } public string Caption { get; set; }
public double X { get; set; } public double MinX { get; set; } public double MaxX { get; set; } public double MeanX { get; set; } public double AverageX { get; set; } public double WeatherInfluencedX { get; set; } public double MoonInfluencedX { get; set; } }
public double GetGrandTotalValue(DateTime start, DateTime stop) { IEnumerable<OneResult> resultingList =
this.ValuesSource.GetValuesForRange(start, stop); return resultingList.Select(res => res.X).Sum(); }
Решение: вычислять только необходимое.
Вывод: не ленитесь создавать отдельные запросы для отдельных нужд.
Нетривиальный ботлнек №4 Вычислялись цифры,
которые впоследствии никуда не выводились.
Решение: попробовать не вычислять её.
Нетривиальный ботлнек №5 Для вычисления одной
из 10 цифр использовалось 50% памяти и 90% CPU.
- Hi, Nikolaj. Do you think “Value X” is that necessary? The matter is, it takes 50% of RAM and 90%
of CPU. Can we remove it? - Hi, Vasiliy. Sure, get rid of it!
Разговор с Product Specialist
Эта цифра бесполезна!!!
Решение: попробовать не вычислять её.
Вывод: нужно знать специфику пользователей, их стандартные User Cases.
Нетривиальный ботлнек №5 Для вычисления одной
из 10 цифр использовалось 50% памяти и 90% CPU.
Решение: переписать Dictionary -> стало занимать в 2,5 раз меньше памяти.
Вывод: используйте оптимальное правильное хранилище для данных.
Нетривиальный ботлнек №6
Всё ещё отжирает кучу памяти.
Оказалось, что самый ресурсоёмкий класс в системе был Dictionary<int, int>.
Решение: Перевести на потоковое чтение данных.
Нетривиальный ботлнек №7
Часто выделялись и освобождались ненужные куски памяти.
Иногда выделяется ещё 200% к уже выделенной памяти.
int[] a1; int[] a2;
// Проще всего написать вот так: public IEnumerable<ItemClass> GetItemsByCondition() { List<int> result = new List<int>(); result.AddRange(this.a1.Where(item => ...condition...)); result.AddRange(this.a2.Where(item => ...condition...)); return result; }
// А надо бы вот так: public IEnumerable<ItemClass> GetItemsByCondition() { foreach (var item in this.a1) if (...condition...) yield return item; foreach (var item in this.a2) if (...condition...) yield return item; }
Например, выбрать элементы по условию
Решение: Перевести на потокровое чтение данных.
Вывод: создавайте как можно меньше коллекций.
Нетривиальный ботлнек №7
Часто выделялись и освобождать ненужные куски памяти.
Иногда выдеяется ещё 200% к уже выделенной памяти.
0) Найти узкое место. 1) Узнать, нужна ли эта функция
пользователю? 2) Нужно ли вызывать именно это место
для достижения результата? 3) Как можно сократить количество
итераций? 4) Оптимизировать код.
Алгоритм борьбы с проблемами
Redgate ANTS – $ JetBrains dotTrace – $ Scitech Memory Profiler - $ EQATEC Profiler – $ nProf – free!!! SlimTune – free!!! ... И т.д. И т.п. И пр.
Профайлер
Redgate ANTS – $400-$800 (удобный, точный, быстрый, много фичей, самый популярный из всех)
JetBrains dotTrace – $400-$800 (чуть менее удобный, чуть менее точный, быстрый, много фичей, free для OpenSource)
Scitech Memory Profiler – $100-$300 (толко для памяти, много фичей, чуть менее удобный)
EQATEC Profiler – $150-$400 (быстрый, память не профайлит, менее точный, free для некоммерческих целей)
nProf – free!!! (но не поддерживается уже 2 года, или больше)
SlimTune – free!!! (но нифига не понятно как им пользоваться, сложный интерфейс)
Профайлер
Посмотрим видео ролики?
ANTS
Конец