12

F# Interactive (and in general REPL-style tools) is an ideal entrance to performance profiling. What could be easier than to select a code block and send it right to a profiler that would come back with performance analysis report. Unfortunately it looks like existing profilers don't have REPL support: you have to either attach a profiler to a process or specify and executable or Web application to profile.

What I end up doing then is wrapping a code block to profile in a unit test and then executing a profile against NUnit command-line session. But is this the best we can do right now with F#?

Vagif Abilov
  • 9,835
  • 8
  • 55
  • 100
  • 1
    I posted a question in RedGate ANTS Profiler forum, and they said they liked the idea and would consider it. – Vagif Abilov Jul 12 '10 at 12:18
  • There's another way to think about profiling - not as measuring time and counting calls, but as asking "What the heck is it doing?" - http://stackoverflow.com/questions/1777556/alternatives-to-gprof/1779343#1779343 – Mike Dunlavey Jul 15 '10 at 15:33

3 Answers3

9

What is the question?

Do you know about the #time command? E.g.

#time "on"
for i in 1..1000000 do
    let r = f(i)
    ignore r

which gives F# interactive output like

--> Timing now on
Real: 00:00:00.000, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0

In any case, I think simply putting the code in an application and running the profile against the app is better than an NUnit test. Either way, yes, it costs you maybe an extra 30 seconds of time to paste the code into a new app and compile it in Release mode. But that's a price I'm happy to pay to get the rich profiling info that Visual Studio provides. Ideally the experience could be better, but I doubt you'll find any REPL-friendly profiling tools today (or tomorrow).

Brian
  • 117,631
  • 17
  • 236
  • 300
  • Yes, but this is useful only in simple cases. It does not give you a picture of how the execution time is split between the operations in the call stack. – Vagif Abilov Jul 12 '10 at 07:51
  • And to answer your question "what is the question?": the question is not about timing execution of an outer call. The question is about performance profiling that is much more than that: it's an extensive performance analysis based on gathered performance data. Modern performance profilers like dotTrace and ANTS can do it by attaching to a process or running an application, but it would be very efficient if they could profile code that is sent to F# Interactive. So the question was whether this can be achieved. – Vagif Abilov Jul 12 '10 at 08:37
4

You can try to use profiler programmatic API to achieve this. I have not tried this, but here are the instruction for ANTS profiler: http://help.red-gate.com/help/ANTSProfiler3/0/en/Topics/AP_UsingTheAPI.html

I think the following might succeed:

  1. Start ANTS profiler and attach to fsi.exe
  2. r "RedGate.Profiler.Api.dll" in fsi

  3. Sprinkle the code you want to profile with RedGate.Profiler.Api.Reset()/RedGate.Profiler.Api.TakeSnapshot()

DotTrace has (had?) similiar API (CPUProfiler.Start()/.StopAndTakeSnapshot()), but I could not find the references for latest versions.

Community
  • 1
  • 1
Dmitry Lomov
  • 1,406
  • 8
  • 8
1

But is this the best we can do right now with F#?

AFAIK, yes. This is a great idea for a feature in the next version of F# or a third-party product though!

J D
  • 48,105
  • 13
  • 171
  • 274