CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на...

34
Как мы оптимизировали ReSharper Скрыган Кирилл, JetBrains

Transcript of CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на...

Page 1: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Как мы оптимизировали ReSharper

Скрыган Кирилл,JetBrains

Page 2: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

DotTrace

Page 3: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Алгоритмическая производительность• DotTrace – как инструмент анализа

производительности• Sampling: почти «честное» время выполнения,

профилирование практически не накладное по производительности

Page 4: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Алгоритмическая производительность• Tracing: дорогое профилирование, не отражает

реального времени выполнения, но показывает количество вызов

• Timeline: инструмент для анализа производительности многопоточных приложений

Page 5: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Типичные продолбы

• Алгоритмический «взрыв» (квадрат или больше)• Ожидание на lock’ах• Memory traffic (о нём поподробнее )

Page 6: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Memory traffic: GC

• В деталях, механику CLR GC не знает никто, кроме самих CLR team. Алгоритмы и принципы CLR GC весьма закрыты.

Kirill Skrygan
2) рассказать про время саспенда для 1ого и 2ого поколения. Что из этого всего делается в бэкграунде
Kirill Skrygan
3) Поколения зависят от конкретной программы. Пример для R#.
Page 7: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Memory traffic: GC

• «Stop-the-world» - блокировка всех трэдов• Чем больше memory traffic – тем чаще вызывается

GC• LOH – Large Object Heap (>82 Кб) – специальная

куча для больших объектов

Kirill Skrygan
2) рассказать про время саспенда для 1ого и 2ого поколения. Что из этого всего делается в бэкграунде
Kirill Skrygan
3) Поколения зависят от конкретной программы. Пример для R#.
Page 8: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Memory traffic

• Стараемся не создавать новых объектов, там, где не нужно.

• Объекты зачастую неожиданно создаются в неочевидных местах.

Page 9: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Замыкания: то, что видим мы

Page 10: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Замыкания: что генерируется

Page 11: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Params: что мы видим

Page 12: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Params всегда аллоцирует объект!

Page 13: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Две лямбды…

Page 14: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

…и только один замыкающий класс!

Page 15: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Yield

Page 16: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Во что компилируется yield

Page 17: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Closure scope

Page 18: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Ну и самое «сладкое»: IList vs List

Page 19: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

List vs IList – думаете IList всегда лучше? IList

List

Page 20: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Memory traffic: прочие примеры

• LinQ, Select and others• Guid.ToString() создаёт дважды. Можно переписать

через stackalloc

Page 21: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

ReSharper: статический анализ

Page 22: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Соображения о структурах данных

• Equals вызывается чаще чем GetEntry? – см. коллизии

• Интернирующие структуры данных• StringSlice – лекарство против SubString

Page 23: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper
Page 24: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

StringSlice в лексере

INTERN

Page 25: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Неочевидные соображения о структурах данных : LocalList

Page 26: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

LOH

• Объекты в LOH никогда не перемещаются• LOH только растет и никогда не уменьшается (т.е.

если объект собран сборщиком мусора, размер LOH все равно остается неизменным)

• Хип LOH освобождается только тогда, когда LOH полностью пуст

• Как следствие – OutOfMemory из-за сильно фрагментированной памяти

Kirill Skrygan
2) рассказать про время саспенда для 1ого и 2ого поколения. Что из этого всего делается в бэкграунде
Kirill Skrygan
3) Поколения зависят от конкретной программы. Пример для R#.
Page 27: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Пример: ChunkList

Page 28: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Boxing

• Очевидные проблемы: используем value types в качестве reference types

• public struct ToBeBoxed : IMySuperInterface {…}• Не забываем что все итераторы – struct’ы!

Page 29: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

.NET method group bug

Delegate target Method group Lambda expression Ratio

Class 329 463 0.71

Interface 24474 461 53.1

Struct 28372 400 71.0

Page 30: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Более общие соображения

• «Кризис среднего возраста» для объектов• Есть смысл задумать о том, в каком поколении

собираются объекты. Желательно, чтобы в Gen0 • WeakReferences – только в крайнем случае.

Page 31: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Caches: тонкости

• LevelDb – храним кэши на диске• DirectMappedCache, LRUWeakReferenceCache –

«вытесняющие» словари с ограниченным размером

Page 32: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

UI Thread: тонкости в обращении

• Chunked operations – прерываем операции в других потоках, чтобы не зависать в UI потоке

• InterruptableReadactivityCookie – операция, прерываемая в том числе по WriteLock.Acquire() из UI потока

Page 33: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Tools

• ReSharper – статический анализ кода на performance issues.

• DotTrace – профилятор• DotMemory, .NET Memory Profiler – memory-

профилятор• DotPeek (ReSharper) – декомпилятор• Ildasm.exe

Page 34: CodeFest 2013. Скрыган К. — Оптимизация .Net приложений на примере Resharper

Вопросы?

Скрыган Кирилл,JetBrains

[email protected]/kskrygan