Proposal - fast path for decode_www_form and few other places

16 views
Skip to first unread message

Daniel Kukula

unread,
Aug 14, 2026, 4:01:06 PM (3 days ago) Aug 14
to elixir-lang-core
I've recently been looking at places where we can avoid building intermediate strings and just copy the existing data instead.
There are two proposals here; the second one is at the end and is independent of the first. For example, unescape in elixir_interpolation.erl, or URI.decode_www_form, which builds an intermediate string: def decode_www_form(string) when is_binary(string), do: unpercent(string, "", true) But if there is no percent sign, we don't need to traverse the string at all: def decode_www_form(string) when is_binary(string) do case :binary.match(string, "%") do :nomatch -> string _ -> unpercent(string, "", true) end end Proposal 1: a fast path Two things fall out of this: - we can return the original binary untouched when there is no percent sign, skipping the traversal entirely - :binary.match returns the position of the first match, so when there is one, we can copy everything up to it into the accumulator in one go instead of byte by byte This is local to each function and doesn't require any new machinery. Proposal 2: precompiled patterns in persistent_term :binary.match has to compile the pattern on every call. We could pass a precompiled one instead, but it then has to be either a parameter to the function or stored somewhere. One such place is persistent_term. Elixir already stores a few things there, so I'd like to precompile the common patterns on application start and look them up: :binary.match(string, :persistent_term.get({:precompiled_pattern, :percent}))
This is something only Elixir can do for its own call sites - a library can already put its own compiled patterns in persistent_term, but nobody outside core can change what URI.decode_www_form matches against.
I'd like to hear your opinion on both.


José Valim

unread,
Aug 14, 2026, 4:34:53 PM (3 days ago) Aug 14
to elixir-l...@googlegroups.com
I recently sent a PR to Erlang/OTP to precompile patterns when they are loaded. Although I believe the single character patterns are very efficient to compile, so unlikely my recent PR will make a large difference.

So to answer question 1, If benchmarks show a gain across the board without persistent term, we can adopt it today, otherwise we wait.

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/elixir-lang-core/4375e915-c5ad-4c09-9d84-690c952aa938n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages