defmodule Adventurous.Util do
defmodule Timer do
defstruct start: System.monotonic_time()
end
@doc """
Times function execution. If msg is specified, prints it with number of ms function exection has taken.
"""
def timed(func, msg \\ nil) do
timer = %Timer{}
result = func.()
diff = time_diff(timer)
if msg do
IO.puts("#{msg}: took #{diff/1_000_000}ms")
end
{result, diff}
end
@doc """
Returns (and optionally prints) time difference between start of timer.
"""
@spec time_diff(atom | %{:start => number, optional(any) => any}) :: number
def time_diff(timer, msg \\ nil) do
diff = System.monotonic_time() - timer.start
if msg do
IO.puts("#{msg}: took #{diff/1_000_000}ms")
end
diff
end
@doc """
Returns left-inclusive and right non-inclusive range.
Range starting and ending at the same number is considered empty.
"""
@spec non_inclusive_range(integer(), integer()) :: Range.t()
def non_inclusive_range(start, stop) do
cond do
start < stop ->
start..(stop - 1)
start > stop ->
stop..(start - 1)
start == stop ->
0..-1//2 # empty range
end
end
end