Skip to content

Commit eac9958

Browse files
authored
Optimize class_attribute_list/1 using an IO data tree (#4172)
Instead of producing intermediate flat lists and joining them via string concatenation using Enum.flat_map/2 and Enum.join/2, this recursive approach builds a deeply nested IO data tree. It evaluates ~1.5x faster and produces significantly less garbage collection pressure since intermediate strings for spaces and joined binaries are no longer allocated.
1 parent ec0c23c commit eac9958

1 file changed

Lines changed: 11 additions & 9 deletions

File tree

lib/phoenix_live_view/html_engine.ex

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -176,17 +176,19 @@ defmodule Phoenix.LiveView.HTMLEngine do
176176
def class_attribute_encode(other),
177177
do: empty_attribute_encode(other)
178178

179-
defp class_attribute_list(value) do
180-
value
181-
|> Enum.flat_map(fn
182-
nil -> []
183-
false -> []
184-
inner when is_list(inner) -> [class_attribute_list(inner)]
185-
other -> [other]
186-
end)
187-
|> Enum.join(" ")
179+
defp class_attribute_list(list), do: class_attribute_list(list, [])
180+
181+
defp class_attribute_list([], acc), do: acc
182+
defp class_attribute_list([nil | t], acc), do: class_attribute_list(t, acc)
183+
defp class_attribute_list([false | t], acc), do: class_attribute_list(t, acc)
184+
185+
defp class_attribute_list([h | t], acc) when is_list(h) do
186+
class_attribute_list(t, class_attribute_list(h, acc))
188187
end
189188

189+
defp class_attribute_list([h | t], []), do: class_attribute_list(t, [to_string(h)])
190+
defp class_attribute_list([h | t], acc), do: class_attribute_list(t, [acc, " ", to_string(h)])
191+
190192
@doc false
191193
def empty_attribute_encode(nil), do: ""
192194
def empty_attribute_encode(false), do: ""

0 commit comments

Comments
 (0)