Подтвердить что ты не робот

Хороший инструмент профилирования производительности 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 #?

4b9b3361

Ответ 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