Skip to content

Commit ae79f84

Browse files
dkukuclaude
andcommitted
Avoid String.split per module in IEx autocomplete
Replace String.split/Enum.at/length with binary_part and :binary.match to extract submodule names. This avoids allocating intermediate lists of string fragments for every matching module. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8b9bf62 commit ae79f84

1 file changed

Lines changed: 12 additions & 6 deletions

File tree

lib/iex/lib/iex/autocomplete.ex

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -509,19 +509,25 @@ defmodule IEx.Autocomplete do
509509
end
510510

511511
defp match_elixir_modules(module, hint) do
512-
name = Atom.to_string(module)
513-
depth = length(String.split(name, ".")) + 1
514-
base = name <> "." <> hint
512+
prefix = Atom.to_string(module) <> "."
513+
prefix_size = byte_size(prefix)
514+
base = prefix <> hint
515515

516516
for mod <- match_modules(base, module == Elixir),
517-
parts = String.split(mod, "."),
518-
depth <= length(parts),
519-
name = Enum.at(parts, depth - 1),
517+
rest = binary_part(mod, prefix_size, byte_size(mod) - prefix_size),
518+
name = elixir_submodule_name(rest),
520519
valid_alias_piece?("." <> name),
521520
uniq: true,
522521
do: %{kind: :module, name: name}
523522
end
524523

524+
defp elixir_submodule_name(rest) do
525+
case :binary.match(rest, ".") do
526+
{pos, _} -> binary_part(rest, 0, pos)
527+
:nomatch -> rest
528+
end
529+
end
530+
525531
defp valid_alias_piece?(<<?., char, rest::binary>>) when char in ?A..?Z,
526532
do: valid_alias_rest?(rest)
527533

0 commit comments

Comments
 (0)