Packages

Tim provides macros for measuring the execution time of an arbitrary Elixir expression.

Current section

Files

Jump to
tim lib tim.ex
Raw

lib/tim.ex

defmodule Tim do
@moduledoc """
`Tim` provides the macro `time` that takes any valid Elixir expression and returns a map
containing several statistics for the expression's execution time, the result of the
evaluated expression, and the expression's string representation. To use
`time`, require or import `Tim` into your environment and pipe in the expression:
```elixir
require Tim
1..10
|> Enum.map(& &1 * 2/((1 + 10) * 10))
|> Enum.sum()
|> Tim.time()
```
This returns (actual timing numbers will vary)
```elixir
%{
expr: "1..10 |> Enum.map(&(&1 * 2 / ((1 + 10) * 10))) |> Enum.sum()",
max: 46,
mean: 46.0,
median: 46,a
min: 46,
n: 1,
result: 1.0
}
```
All times are in microseconds.
The `time` macro takes a second argument that is the number `n` of times the expression
is executed to gather timing statistics. When the above expression is piped into
`Time.time(100)`, the result will look something like
```elixir
%{
expr: "1..10 |> Enum.map(&(&1 * 2 / ((1 + 10) * 10))) |> Enum.sum()",
max: 71,
mean: 13.83,
median: 12,
min: 10,
n: 100,
result: 1.0
}
```
"""
alias Tim.Stats
@doc """
Takes an Elixir expression and returns a map of timing stats after executing
the provided expression `n` times.
"""
defmacro time(expr, n \\ 1) when is_integer(n) do
expr_string = Macro.to_string(expr)
quote do
{times, [result | _]} =
Enum.map(1..unquote(n), fn _ ->
:timer.tc(fn -> unquote(expr) end)
end)
|> Enum.unzip()
Map.merge(
%{expr: unquote(expr_string), n: unquote(n), result: result},
Stats.collect(times)
)
end
end
end