perf: fix medium-severity N+1 and inefficiency patterns
- pending_edit_for_user: add preload for [:user, :contact] to avoid lazy-loaded N+1 when templates access those associations - ScoresController.encode_binary: combine 3 Enum.map passes into a single Enum.reduce, halving list traversals for score binary encoding - find_duplicate_contact: push station-pair/grid matching into SQL WHERE clause so dedup uses the DB index instead of loading all matching rows + Enum.find in Elixir
This commit is contained in:
parent
473c2ab0ec
commit
9cce257db7
2 changed files with 13 additions and 16 deletions
|
|
@ -757,25 +757,18 @@ defmodule Microwaveprop.Radio do
|
||||||
min_ts = DateTime.add(ts, -@dedup_window_seconds, :second)
|
min_ts = DateTime.add(ts, -@dedup_window_seconds, :second)
|
||||||
max_ts = DateTime.add(ts, @dedup_window_seconds, :second)
|
max_ts = DateTime.add(ts, @dedup_window_seconds, :second)
|
||||||
|
|
||||||
expected_pair = Enum.sort([{s1, g1}, {s2, g2}])
|
|
||||||
|
|
||||||
from(c in Contact,
|
from(c in Contact,
|
||||||
where:
|
where:
|
||||||
c.band == ^band_decimal and
|
c.band == ^band_decimal and
|
||||||
c.qso_timestamp >= ^min_ts and
|
c.qso_timestamp >= ^min_ts and
|
||||||
c.qso_timestamp <= ^max_ts and
|
c.qso_timestamp <= ^max_ts and
|
||||||
c.flagged_invalid == false
|
c.flagged_invalid == false and
|
||||||
|
fragment("LEAST(UPPER(station1), UPPER(station2)) = ?", ^min(s1, s2)) and
|
||||||
|
fragment("GREATEST(UPPER(station1), UPPER(station2)) = ?", ^max(s1, s2)) and
|
||||||
|
fragment("LEAST(UPPER(grid1), UPPER(grid2)) = ?", ^min(g1, g2)) and
|
||||||
|
fragment("GREATEST(UPPER(grid1), UPPER(grid2)) = ?", ^max(g1, g2))
|
||||||
)
|
)
|
||||||
|> Repo.all()
|
|> Repo.one()
|
||||||
|> Enum.find(fn c ->
|
|
||||||
pair =
|
|
||||||
Enum.sort([
|
|
||||||
{String.upcase(c.station1), String.upcase(c.grid1)},
|
|
||||||
{String.upcase(c.station2), String.upcase(c.grid2)}
|
|
||||||
])
|
|
||||||
|
|
||||||
pair == expected_pair
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@refinement_fields ~w(grid1 grid2 mode)a
|
@refinement_fields ~w(grid1 grid2 mode)a
|
||||||
|
|
@ -1101,6 +1094,7 @@ defmodule Microwaveprop.Radio do
|
||||||
def pending_edit_for_user(contact_id, user_id) do
|
def pending_edit_for_user(contact_id, user_id) do
|
||||||
ContactEdit
|
ContactEdit
|
||||||
|> where([e], e.contact_id == ^contact_id and e.user_id == ^user_id and e.status == :pending)
|
|> where([e], e.contact_id == ^contact_id and e.user_id == ^user_id and e.status == :pending)
|
||||||
|
|> preload([:user, :contact])
|
||||||
|> Repo.one()
|
|> Repo.one()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,9 +103,12 @@ defmodule MicrowavepropWeb.ScoresController do
|
||||||
|
|
||||||
header = <<"PSCR", 1::8, 0::8, 0::8, 0::8, cell_count::little-32>>
|
header = <<"PSCR", 1::8, 0::8, 0::8, 0::8, cell_count::little-32>>
|
||||||
|
|
||||||
lats = scores |> Enum.map(&<<&1.lat * 1.0::little-float-32>>) |> IO.iodata_to_binary()
|
{lats, lons, score_bytes} =
|
||||||
lons = scores |> Enum.map(&<<&1.lon * 1.0::little-float-32>>) |> IO.iodata_to_binary()
|
Enum.reduce(scores, {[], [], []}, fn s, {lats_acc, lons_acc, scs_acc} ->
|
||||||
score_bytes = scores |> Enum.map(&<<clamp_score(&1.score)::8>>) |> IO.iodata_to_binary()
|
{[<<s.lat * 1.0::little-float-32>> | lats_acc],
|
||||||
|
[<<s.lon * 1.0::little-float-32>> | lons_acc],
|
||||||
|
[<<clamp_score(s.score)::8>> | scs_acc]}
|
||||||
|
end)
|
||||||
|
|
||||||
<<header::binary, lats::binary, lons::binary, score_bytes::binary>>
|
<<header::binary, lats::binary, lons::binary, score_bytes::binary>>
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue