Skip to content

Commit

Permalink
Fixed eprof to work with multiple processes (elixir-lang#7317)
Browse files Browse the repository at this point in the history
  • Loading branch information
costaraphael authored and josevalim committed Feb 6, 2018
1 parent f0ad7ed commit 252974e
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 11 deletions.
36 changes: 25 additions & 11 deletions lib/mix/lib/mix/tasks/profile.eprof.ex
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ defmodule Mix.Tasks.Profile.Eprof do
def profile(fun, opts) do
fun
|> profile_and_analyse(opts)
|> print_output
|> print_output()
end

defp profile_and_analyse(fun, opts) do
Expand All @@ -165,11 +165,15 @@ defmodule Mix.Tasks.Profile.Eprof do
:eprof.profile([], fun, matching_pattern(opts))

results =
:eprof.dump()
|> extract_results
|> filter_results(opts)
|> sort_results(opts)
|> add_totals
Enum.map(:eprof.dump(), fn {pid, call_results} ->
parsed_calls =
call_results
|> filter_results(opts)
|> sort_results(opts)
|> add_totals()

{pid, parsed_calls}
end)

:eprof.stop()

Expand All @@ -191,9 +195,6 @@ defmodule Mix.Tasks.Profile.Eprof do
end
end

defp extract_results([]), do: []
defp extract_results([{_pid, call_results}]), do: call_results

defp filter_results(call_results, opts) do
calls_opt = Keyword.get(opts, :calls, 0)
time_opt = Keyword.get(opts, :time, 0)
Expand Down Expand Up @@ -227,14 +228,23 @@ defmodule Mix.Tasks.Profile.Eprof do

@header ["#", "CALLS", "%", "TIME", "µS/CALL"]

defp print_output({0, _, _, _}), do: print_function_count(0)
defp print_output([]) do
print_function_count(0)
end

defp print_output(results) do
Enum.each(results, &print_result/1)
end

defp print_output({function_count, call_results, call_count, total_time}) do
defp print_result({pid, {function_count, call_results, call_count, total_time}}) do
formatted_rows = Enum.map(call_results, &format_row(&1, total_time))
formatted_total = format_total(total_time, call_count)

column_lengths = column_lengths(@header, formatted_rows)

IO.puts("")

print_pid_row(pid)
print_row(@header, column_lengths)
print_row(formatted_total, column_lengths)
Enum.each(formatted_rows, &print_row(&1, column_lengths))
Expand All @@ -244,6 +254,10 @@ defmodule Mix.Tasks.Profile.Eprof do
print_function_count(function_count)
end

defp print_pid_row(pid) do
IO.puts("Profile results of #{inspect(pid)}")
end

defp format_row({{module, function, arity}, {count, time}}, total_time) do
mfa = Exception.format_mfa(module, function, arity)
time_percentage = :erlang.float_to_binary(100 * divide(time, total_time), [{:decimals, 2}])
Expand Down
8 changes: 8 additions & 0 deletions lib/mix/test/mix/tasks/profile.eprof_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ defmodule Mix.Tasks.Profile.EprofTest do
end
end

test "profiles evaluated expression in multiple processes", context do
in_tmp context.test, fn ->
assert capture_io(fn ->
Eprof.run(["-e", "spawn(fn -> #{@expr} end)"])
end) =~ ~r(String\.Chars\.Integer\.to_string\/1\s+\d)
end
end

test "profiles the script", context do
in_tmp context.test, fn ->
profile_script_name = "profile_script.ex"
Expand Down

0 comments on commit 252974e

Please sign in to comment.