Skip to content

Commit 0f39750

Browse files
authored
Build each pair as a single binary in URI.encode_query (#15983)
Encode each value directly into the accumulator that contains the encoded key and delimiter. This avoids intermediate binary allocations and string concatenations for each pair.
1 parent 7a40579 commit 0f39750

1 file changed

Lines changed: 6 additions & 11 deletions

File tree

‎lib/elixir/lib/uri.ex‎

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,13 @@ defmodule URI do
169169
raise ArgumentError, "encode_query/2 values cannot be lists, got: #{inspect(value)}"
170170
end
171171

172-
defp encode_kv_pair({key, value}, :rfc3986) do
173-
encode_unreserved(Kernel.to_string(key), :percent) <>
174-
"=" <> encode_unreserved(Kernel.to_string(value), :percent)
175-
end
172+
defp encode_kv_pair({key, value}, :rfc3986), do: encode_kv_pair(key, value, :percent)
173+
defp encode_kv_pair({key, value}, :www_form), do: encode_kv_pair(key, value, :www_form)
176174

177-
defp encode_kv_pair({key, value}, :www_form) do
178-
encode_www_form(Kernel.to_string(key)) <> "=" <> encode_www_form(Kernel.to_string(value))
175+
# The value is appended to the encoded key, so each pair is built as a single binary
176+
defp encode_kv_pair(key, value, mode) do
177+
key = encode_unreserved(Kernel.to_string(key), "", mode)
178+
encode_unreserved(Kernel.to_string(value), <<key::binary, ?=>>, mode)
179179
end
180180

181181
@doc """
@@ -454,11 +454,6 @@ defmodule URI do
454454
encode_unreserved(string, "", :www_form)
455455
end
456456

457-
# Matching upfront keeps the empty case from allocating the accumulator.
458-
defp encode_unreserved(<<>>, _mode), do: ""
459-
460-
defp encode_unreserved(string, mode), do: encode_unreserved(string, "", mode)
461-
462457
defp encode_unreserved(<<?\s, rest::binary>>, acc, :www_form) do
463458
encode_unreserved(rest, <<acc::binary, ?+>>, :www_form)
464459
end

0 commit comments

Comments
 (0)