Skip to content

Optimize path splitting - #1323

Merged
josevalim merged 1 commit into
elixir-plug:mainfrom
preciz:optimize-path-splitting
Aug 26, 2026
Merged

Optimize path splitting#1323
josevalim merged 1 commit into
elixir-plug:mainfrom
preciz:optimize-path-splitting

Conversation

@preciz

@preciz preciz commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Assisted-by: Codex CLI:GPT 5.6 Sol

Less code, ~20% faster, uses half the memory.

Bench:

Mix.install([:benchee])

paths = [
  "/",
  "/health",
  "/api/v1/users/42",
  "/api/v1/users/42/profile",
  "/oauth/callback/github",
  "/assets/app-3f2a1c9.js",
  "/images/products/2026/08/widget-large.webp",
  "/de/products/electronics/wireless-headphones",
  "/organizations/acme/projects/plug/pull_requests/123/files",
  "/.well-known/acme-challenge/7f86c2d1",
  "/api//v1/orders/123/"
]

split_and_filter = fn path ->
  segments = :binary.split(path, "/", [:global])
  for segment <- segments, segment != "", do: segment
end

split_with_trim = fn path ->
  :binary.split(path, "/", [:global, :trim_all])
end

Benchee.run(
  %{
    "split + filter (before)" => fn -> Enum.map(paths, split_and_filter) end,
    "split with trim_all (after)" => fn -> Enum.map(paths, split_with_trim) end
  },
  time: 3,
  warmup: 1,
  memory_time: 1,
  reduction_time: 1,
  pre_check: :all_same
)

Results:

Operating System: Linux
CPU Information: AMD Ryzen 7 8845HS w
Number of Available Cores: 16
Available memory: 54.72 GB
Elixir 1.20.3
Erlang 29.0.5
JIT enabled: true

Benchmark suite executing with the following configuration:
warmup: 1 s
time: 3 s
memory time: 1 s
reduction time: 1 s
parallel: 1
inputs: none specified
Estimated total run time: 12 s
Excluding outliers: false

Benchmarking split + filter (before) ...
Benchmarking split with trim_all (after) ...
Calculating statistics...
Formatting results...

Name                                  ips        average  deviation         median         99th %
split with trim_all (after)      555.38 K        1.80 μs   ±323.04%        1.73 μs        2.30 μs
split + filter (before)          380.62 K        2.63 μs   ±251.43%        2.48 μs        4.76 μs

Comparison: 
split with trim_all (after)      555.38 K
split + filter (before)          380.62 K - 1.46x slower +0.83 μs

Memory usage statistics:

Name                           Memory usage
split with trim_all (after)         1.29 KB
split + filter (before)             2.89 KB - 2.24x memory usage +1.60 KB

**All measurements for memory usage were the same**

Reduction count statistics:

Name                        Reduction count
split with trim_all (after)              62
split + filter (before)                 282 - 4.55x reduction count +220

**All measurements for reduction count were the same**

@josevalim
josevalim merged commit 7f16342 into elixir-plug:main Aug 26, 2026
2 checks passed
@josevalim

Copy link
Copy Markdown
Member

💚 💙 💜 💛 ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants