Хороший инструмент профилирования производительности F # - PullRequest
18 голосов
/ 01 ноября 2011

Кто-нибудь может порекомендовать инструмент для профилирования производительности с хорошей поддержкой F #?

Я использовал профилировщик Visual Studio 2010, но обнаружил несколько проблем при использовании F #.Мне кажется, что я профилирую байт-код после отражения, а не исходный 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 #?

Ответы [ 2 ]

7 голосов
/ 01 ноября 2011

Мой ответ может вас разочаровать, но он может быть полезен.

Несколько месяцев назад я пытался найти хороший бесплатный .NET профилировщик для моего проекта F #.Мой опыт работы с nprof , slimtune , EQATEC и (недавно коммерческим) Xte profiler совсем не был приличным.Я обнаружил, что их поддержка F # была очень ограниченной, и мне пришлось вернуться к профилировщику Visual Studio 2010.Я думаю, что ваша лучшая ставка здесь - это какой-то коммерческий профилировщик (с которым у меня нет опыта).

Через некоторое время я привыкаю к ​​профилировщику и вижу его представление результатов простым, ясным и понятным.Если бы вы оптимизировали параллельные программы, использование Concurrent Visualizer было бы неизбежным.Тем не менее, единственное, что вас волнует, это производительность;хорошо ладить с профайлером VS 2010 стоит попробовать.

Для профилирования кода F # я также считаю CLR Profiler и ILSpy достойным упоминания.Первый может визуализировать кучи в случае, если вы хотите минимизировать выделение памяти или сборку мусора.Последний может создавать эквивалентный код в IL или C # (с которым я знаком больше, чем с F #);это может помочь понять, как конструкции высокого порядка в F # работают, чтобы правильно их использовать.

ОБНОВЛЕНИЕ:

Дейв Томас написал отличный блогpost , где он использовал несколько коммерческих профилировщиков для обнаружения утечек памяти и настройки асинхронного приложения.Посмотрите на эти профилировщики;они могут удовлетворить ваши предпочтения.

4 голосов
/ 01 ноября 2011

Звучит как ваше профилирование в режиме отладки.Вам нужно включить «Оптимизировать код» из проекта -> свойства -> меню сборки.Вы также можете профилировать в режиме выпуска, который включен по умолчанию.Если вы этого не сделаете, будет много вызовов вызова и создания объектов Tuple среди прочего.

Вышеприведенная функция MultiAdd не является хвостовой рекурсивной.Если бы это было так, вам также нужно было бы включить «Генерировать хвостовые вызовы» в режиме отладки для профилирования.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...