Elixir 1.1.1 has been recently released and the includes built in profiling support with mix profile.fprof . I decied to take this new command for a spin. I’ve used fprof before so I’ll desribe some of the differences about using the new mix version.

This will be a short post, but hopefully useful or interesting.

Results Format

I’m using my game of life implementation that I wrote about in the past. I had previously setup profiling options for this program, including support for fprof. There are some differences between the reporing when using fprof directly and with the new mix profile.fprof support. With mix, I’ve enabled all the options I used with fprof before, and here’s the output:

MIX_ENV=prod time mix profile.fprof --callers=true --sort=own --details -e "Profile.run_test" CNT ACC (ms) OWN (ms) Total 81526 1042.615 1031.268 Enum."-reduce/3-lists^foldl/2-0-"/3 2900 0.000 38.851 Enum."-reduce/3-lists^foldl/2-0-"/3 2900 0.000 38.333 Enum."-reduce/3-lists^foldl/2-0-"/3 2900 0.000 37.715 Enum."-reduce/3-lists^foldl/2-0-"/3 2900 0.000 37.498 Enum."-reduce/3-lists^foldl/2-0-"/3 2900 0.000 36.128 Enum."-reduce/3-lists^foldl/2-0-"/3 1010 0.000 13.145 Enum.reduce/3 601 161.130 9.827 Enum.reduce/3 601 161.082 9.593 Enum.reduce/3 601 159.431 9.464 Enum.reduce/3 601 160.294 9.230 Enum.reduce/3 601 154.103 8.899 Enum.reduce/3 20 829.270 4.894 Enum."-reduce/3-lists^foldl/2-0-"/3 18535 1625.310 253.577 <-- Enum."-reduce/3-lists^foldl/2-0-"/3 2900 0.000 38.851 Enum."-reduce/3-lists^foldl/2-0-"/3 2900 0.000 38.333 Enum."-reduce/3-lists^foldl/2-0-"/3 2900 0.000 37.715 Enum."-reduce/3-lists^foldl/2-0-"/3 2900 0.000 37.498 Enum."-reduce/3-lists^foldl/2-0-"/3 2900 0.000 36.128 anonymous fn/3 in Enum.map/2 900 159.238 14.991 anonymous fn/3 in Enum.map/2 900 158.584 14.887 anonymous fn/3 in Enum.map/2 900 159.389 14.852 ...

This is nice and readable. The anonymous functions are still a little hard to fillow but that’s just a problem with functions not having names. The data is organized is nice columns and easy to follow.

To contrast, here’s the direct fprof output:

% MIX_ENV=prod mix run -e "Profile.fprof" %% Analysis results: { anlysis_options , [{ callers , true }, { sort , own }, { totals , true }, { details , true }]}. % CNT ACC OWN [{ totals , 81530 , 985 . 003 , 977 . 102 }]. %%% {[{ { 'Elixir.Enum' , '-reduce/3-lists^foldl/2-0-' , 3 }, 2900 , 0 . 000 , 42 . 280 }, { { 'Elixir.Enum' , '-reduce/3-lists^foldl/2-0-' , 3 }, 2900 , 0 . 000 , 37 . 985 }, { { 'Elixir.Enum' , '-reduce/3-lists^foldl/2-0-' , 3 }, 2900 , 0 . 000 , 36 . 809 }, { { 'Elixir.Enum' , '-reduce/3-lists^foldl/2-0-' , 3 }, 2900 , 0 . 000 , 36 . 663 }, { { 'Elixir.Enum' , '-reduce/3-lists^foldl/2-0-' , 3 }, 2900 , 0 . 000 , 21 . 512 }, { { 'Elixir.Enum' , '-reduce/3-lists^foldl/2-0-' , 3 }, 1010 , 0 . 000 , 12 . 211 }, { { 'Elixir.Enum' , reduce , 3 }, 601 , 178 . 067 , 9 . 724 }, { { 'Elixir.Enum' , reduce , 3 }, 601 , 158 . 718 , 9 . 110 }, { { 'Elixir.Enum' , reduce , 3 }, 601 , 162 . 003 , 9 . 077 }, { { 'Elixir.Enum' , reduce , 3 }, 601 , 158 . 718 , 9 . 006 }, { { 'Elixir.Enum' , reduce , 3 }, 601 , 91 . 765 , 5 . 222 }, { { 'Elixir.Enum' , reduce , 3 }, 20 , 778 . 835 , 3 . 958 }], { { 'Elixir.Enum' , '-reduce/3-lists^foldl/2-0-' , 3 }, 18535 , 1528 . 106 , 233 . 557 }, % [{ { 'Elixir.Enum' , '-reduce/3-lists^foldl/2-0-' , 3 }, 2900 , 0 . 000 , 42 . 280 }, { { 'Elixir.Enum' , '-reduce/3-lists^foldl/2-0-' , 3 }, 2900 , 0 . 000 , 37 . 985 }, { { 'Elixir.Enum' , '-reduce/3-lists^foldl/2-0-' , 3 }, 2900 , 0 . 000 , 36 . 809 }, { { 'Elixir.Enum' , '-reduce/3-lists^foldl/2-0-' , 3 }, 2900 , 0 . 000 , 36 . 663 }, { { 'Elixir.Enum' , '-reduce/3-lists^foldl/2-0-' , 3 }, 2900 , 0 . 000 , 21 . 512 }, { { 'Elixir.Enum' , '-map/2-fun-0-' , 3 }, 900 , 176 . 149 , 16 . 459 }, { { 'Elixir.Life' , '-list_of_neighbors/3-fun-0-' , 6 }, 900 , 59 . 302 , 15 . 913 }, { { 'Elixir.Enum' , '-map/2-fun-0-' , 3 }, 900 , 160 . 314 , 14 . 960 }, { { 'Elixir.Enum' , '-map/2-fun-0-' , 3 }, 900 , 157 . 062 , 14 . 751 }, { { 'Elixir.Enum' , '-map/2-fun-0-' , 3 }, 900 , 157 . 090 , 14 . 670 }, ...

This data is still organized in columns, kind of. The “{}” make things a little difficult to follow. It also has the “Elixir.” annotations because it’s in Erlang format.

Peronsally (i.e. as a person) I find the new mix form easier to read. But, if I were writing a program to process the output and transform it or analyze it then the standard fprof format would be preferable. Especially if was writing that program in Elixir or Erlang - the output from fprof is a set of Erlang terms. The results should be directly consumable by an Erlang or Elixir program.

In fact, I’m assuming that mix profile.fprof takes in this format and transforms it into the human readable format we see when the running the command.

If you want to setup standard fprof yourself see my older post Profiling Elixir. But if you just want human readable results the mix profile.fprof command will serve your well.

In might be interesting if a future version of mix profile.fprof had a variant that could return the raw analysis as an Elixir structure.

Next Week

That’s all for fprof for now.

Next week’s I’lldescribe some of the interesting talks I saw last week at Elixir Conf 2015.