Хороший инструмент профилирования производительности F #
Можно ли рекомендовать инструмент профилирования производительности с хорошей поддержкой F #?
Я использовал профилировщик Visual Studio 2010, но Ive обнаружил несколько проблем при использовании F #. Это больше похоже на Im профилирование байтового кода после отражения, чем исходный F #.
Например, при профилировании следующего немного надуманного примера:
let Add a b =
a + b
let Add1 = Add 1
let rec MultiAdd count =
match count with
| 1 -> 1
| _ -> (Add1 1) + (MultiAdd (count - 1))
MultiAdd 10000 |> ignore
Я получаю следующее дерево вызовов:
![CallTree]()
Когда я просматриваю Microsoft.FSharp.Core.FSharpFunc`2.Invoke(0) в функции Подробности, я вижу:
![Function Details]()
Я понимаю, что то, что я вижу, основано на базовой реализации скомпилированного кода, и хотя я могу следовать за ним, это сложно.
Есть ли у кого-нибудь опыт использования других инструментов профилирования с F #, и они лучше выполняют сопоставление с исходным кодом F #?
Ответы
Ответ 1
Мой ответ может вас разочаровать, но это может быть полезно.
Несколько месяцев назад я попытался найти хороший бесплатный.NET-профайлер для моего проекта F #. Мой опыт работы с nprof, slimtune, EQATEC и (недавно коммерческий) Xte profiler не был приличным вообще. Я нашел, что их поддержка F # была очень ограниченной, и мне пришлось вернуться к профилировщику Visual Studio 2010. Я считаю, что ваш лучший выбор - это какой-то коммерческий профайлер (с которым у меня нет опыта).
Через некоторое время я привык к профилировщику и вижу его представление результатов простым, понятным и понятным. Если бы вы оптимизировали параллельные программы, использование Concurrent Visualizer было бы неизбежным. Тем не менее, единственное, что вам нужно - это производительность; хорошо работать с профилировщиком VS 2010 стоит попробовать.
Для профилирования кода F # я также нахожу CLR Profiler и ILSpy стоит упомянуть. Первые могут визуализировать кучи в случае, если вы хотите минимизировать распределение памяти или сбор мусора. Последний может создавать эквивалентный код в IL или С# (который я больше знаком с F #); это может помочь понять, как работают конструкторы высокого порядка в F #, чтобы использовать их соответствующим образом.
UPDATE:
Дэйв Томас написал отличное сообщение в блоге, где использовал несколько коммерческих профилографов для обнаружения утечек памяти и настройки асинхронного приложения. Взгляните на эти профилировщики; они могут удовлетворить ваши предпочтения.
Ответ 2
Это похоже на профилирование в режиме отладки. Вам нужно включить "Оптимизировать код" в меню проекта → properties → build. Вы также можете просмотреть профиль в режиме выпуска, который по умолчанию включен. Если вы этого не сделаете, будет много вызовов вызова и создания объекта Tuple между прочим.
Функция MultiAdd выше не является рекурсивной. Если это так, вам также необходимо включить "Генерировать хвостовые вызовы" в режиме Debug для профилирования.
![enter image description here]()
Это также будет хорошим примером для оптимизации хвостового вызова.
let Add a b =
a + b
let Add1 = Add 1
let rec MultiAdd total count =
match count with
| 1 -> 1 + total
| _ -> MultiAdd (count - 1) (total + Add1 1)
MultiAdd 10000 0 |> ignore
![enter image description here]()