[ANN] PProf.jl -- Explore profiles in style

@NHDaly and I recently put our heads together and created an export from Julia’s statistical profiler to pprof (a Go based analysis and visualization tool), you can export profiles – send them to a friend; get some nice and responsive flamegraphs; plot weighted callgraphs; diff two profiles, etc!

PProf.jl is registered and if you run into issues please report them over at https://github.com/vchuravy/PProf.jl

Take a look at https://blog.golang.org/profiling-go-programs for some examples what pprof can do.


Profiling your code? More like gofiling your code, amirite

[exits stage left]


Updated announcement:

PProf.jl now embeds the precompiled google/pprof so you can now just install PProf.jl and start profiling! And on MacOS, Linux, and Windows!

using Profile, PProf

# collect a profile
@profile peakflops()

# Export pprof profile and open interactive profiling web interface.

This immediately (by default) launches an interactive profile viewer in your browser:

It also exports the profile to disk under the name provided in out = "", so you can share the exported profiles with friends, or even diff two profiles.

For now, we don’t provide any julia API on top of the embedded go/pprof binary, but you can access the binary via PProf.go_pprof, e.g.:

run(`$(PProf.go_pprof) -web -diff_base prof1 prof2`)

pretty cool! 2 questions:

  • Is it possible to run @async pprof() asynchronously and always have the current profile buffer displayed?
  • pprof() always makes chrome pop up after a few seconds, is there a way to avoid this?

web = false will just export the profile to disk (named via the out=profile.pb.gz flag), and will not start the webserver. Currently there is no way to start the webserver and not open chrome; I think the pprof binary opens the link automatically (like jupyter).

Hmm, i just tried, and while yeah you can totally run pprof() asynchronously, it doesn’t look like pprof watches your profile file. It seems to load the data into memory and then use it, so I don’t think you can update it like that…

It probably wouldn’t be too hard to keep a global instance of pprof running asynchronously and restart it when you build a new profile! That would be a nice feature! (Wanna send a PR? :stuck_out_tongue:)

@gdkrmr Maybe something like this:

julia> using Profile, PProf

julia> const port = 24234;

julia> function reload_pprof()
           global pp
           if @isdefined(pp)
           pp = run(`$(PProf.go_pprof) -http=localhost:$port profile.pb.gz`, wait=false)

julia> reload_pprof()
Process(`/Users/nathan.daly/.julia/packages/PProf/5oWcL/deps/usr/bin/pprof -http=localhost:24234 profile.pb.gz`, ProcessRunning)

julia> @profile peakflops()

julia> pprof(web=false)

julia> reload_pprof();
Process(`/Users/nathan.daly/.julia/packages/PProf/5oWcL/deps/usr/bin/pprof -http=localhost:24234 profile.pb.gz`, ProcessRunning)
1 Like

made a PR :slight_smile: