Skip to content

Commit

Permalink
Merge pull request #25 from hissssst/main
Browse files Browse the repository at this point in the history
Hot path optimizations
  • Loading branch information
rkallos authored Dec 30, 2024
2 parents fe17587 + cba7aca commit 1ff7ae6
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 20 deletions.
94 changes: 83 additions & 11 deletions lib/peep/buckets/custom.ex
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,95 @@ defmodule Peep.Buckets.Custom do
end
end

## Bucket binary search

defp bucket_for_ast(buckets) do
bucket_defns =
for {boundary, bucket_idx} <- Enum.with_index(buckets) do
quote do
def bucket_for(n, _) when n < unquote(boundary), do: unquote(bucket_idx)
end
int_buckets = int_buckets(buckets, nil, 0)

float_buckets =
buckets
|> Enum.map(&(&1 * 1.0))
|> Enum.with_index()

variable = Macro.var(:x, nil)

int_length = length(int_buckets)
int_tree = build_bucket_tree(int_buckets, int_length, length(buckets), variable)

float_length = length(float_buckets)
float_tree = build_bucket_tree(float_buckets, float_length, length(buckets), variable)

quote do
def bucket_for(unquote(variable), _) when is_integer(unquote(variable)) do
unquote(int_tree)
end

final_defn =
quote do
def bucket_for(_, _), do: unquote(length(buckets))
def bucket_for(unquote(variable), _) when is_float(unquote(variable)) do
unquote(float_tree)
end
end

bucket_defns ++ [final_defn]
# |> tap(&IO.puts(Code.format_string!(Macro.to_string(&1))))
end

defp build_bucket_tree([{bound, lval}], 1, rval, variable) do
quote do
case unquote(variable) do
x when x < unquote(bound) ->
unquote(lval)

_ ->
unquote(rval)
end
end
end

defp build_bucket_tree([{lbound, lval}, {rbound, mval}], 2, rval, variable) do
quote do
case unquote(variable) do
x when x < unquote(lbound) ->
unquote(lval)

x when x < unquote(rbound) ->
unquote(mval)

_ ->
unquote(rval)
end
end
end

defp build_bucket_tree(bounds, length, rval, variable) do
llength = div(length, 2)
rlength = length - llength - 1

{lbounds, rbounds} = Enum.split(bounds, llength)
[{bound, lval} | rbounds] = rbounds

quote do
case unquote(variable) do
x when x < unquote(bound) ->
unquote(build_bucket_tree(lbounds, llength, lval, variable))

_ ->
unquote(build_bucket_tree(rbounds, rlength, rval, variable))
end
end
end

defp int_buckets([], _prev, _counter) do
[]
end

defp int_buckets([curr | tail], prev, counter) do
case ceil(curr) do
^prev -> int_buckets(tail, prev, counter + 1)
curr -> [{curr, counter} | int_buckets(tail, curr, counter + 1)]
end
end

## Upper bound

defp upper_bound_ast(buckets) do
bucket_defns =
for {boundary, bucket_idx} <- Enum.with_index(buckets) do
Expand All @@ -67,7 +140,6 @@ defmodule Peep.Buckets.Custom do
end

defp int_to_float_string(int) do
# kind of a hack, but nothing else came to mind
to_string(:math.pow(int, 1))
to_string(int * 1.0)
end
end
33 changes: 24 additions & 9 deletions lib/peep/event_handler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ defmodule Peep.EventHandler do
@moduledoc false
require Logger

@compile :inline

alias Telemetry.Metrics.{Counter, Summary, Distribution}

def attach(metrics, name, global_tags) do
Expand All @@ -28,7 +30,8 @@ defmodule Peep.EventHandler do
end

def detach(handler_ids) do
Enum.each(handler_ids, fn id -> :telemetry.detach(id) end)
for id <- handler_ids, do: :telemetry.detach(id)
:ok
end

def handle_event(_event, measurements, metadata, %{
Expand All @@ -37,12 +40,19 @@ defmodule Peep.EventHandler do
global_tags: global_tags
}) do
for metric <- metrics do
if value = keep?(metric, metadata) && fetch_measurement(metric, measurements, metadata) do
%{
measurement: measurement,
tag_values: tag_values,
tags: tags,
keep: keep
} = metric

if value = keep?(keep, metadata) && fetch_measurement(measurement, measurements, metadata) do
tag_values =
global_tags
|> Map.merge(metric.tag_values.(metadata))
|> Map.merge(tag_values.(metadata))

tags = Map.new(metric.tags, &{&1, Map.get(tag_values, &1, "")})
tags = Map.new(tags, &{&1, Map.get(tag_values, &1, "")})

Peep.insert_metric(name, metric, value, tags)
end
Expand All @@ -53,15 +63,15 @@ defmodule Peep.EventHandler do
{__MODULE__, peep_name, event_name}
end

defp keep?(%{keep: nil}, _metadata), do: true
defp keep?(%{keep: keep}, metadata), do: keep.(metadata)
defp keep?(nil, _metadata), do: true
defp keep?(keep, metadata), do: keep.(metadata)

defp fetch_measurement(%Counter{}, _measurements, _metadata) do
1
end

defp fetch_measurement(metric, measurements, metadata) do
case metric.measurement do
defp fetch_measurement(measurement, measurements, metadata) do
case measurement do
nil ->
nil

Expand All @@ -72,7 +82,12 @@ defmodule Peep.EventHandler do
fun.(measurements, metadata)

key ->
measurements[key] || 1
case measurements do
%{^key => nil} -> 1
%{^key => false} -> 1
%{^key => value} -> value
_ -> 1
end
end
end

Expand Down
2 changes: 2 additions & 0 deletions lib/peep/storage/striped.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ defmodule Peep.Storage.Striped do

@type tids() :: %{pos_integer() => :ets.tid()}

@compile :inline

@spec new() :: tids()
@impl true
def new() do
Expand Down

0 comments on commit 1ff7ae6

Please sign in to comment.