Skip to content

Commit e0480b6

Browse files
michalmuskalajosevalim
authored andcommitted
Optimize String.replace_* functions (#6240)
1 parent 5e507f3 commit e0480b6

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

lib/elixir/lib/string.ex

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -666,15 +666,15 @@ defmodule String do
666666

667667
defp replace_leading(string, match, replacement, prefix_size, suffix_size, acc) when suffix_size >= 0 do
668668
case string do
669-
<<prefix::size(prefix_size)-binary, suffix::size(suffix_size)-binary>> when prefix == match ->
669+
<<prefix::size(prefix_size)-binary, suffix::binary>> when prefix == match ->
670670
replace_leading(suffix, match, replacement, prefix_size, suffix_size - prefix_size, acc + 1)
671671
_ ->
672-
duplicate(replacement, acc) <> string
672+
prepend_unless_empty(duplicate(replacement, acc), string)
673673
end
674674
end
675675

676676
defp replace_leading(string, _match, replacement, _prefix_size, _suffix_size, acc) do
677-
duplicate(replacement, acc) <> string
677+
prepend_unless_empty(duplicate(replacement, acc), string)
678678
end
679679

680680
@doc """
@@ -714,15 +714,15 @@ defmodule String do
714714

715715
defp replace_trailing(string, match, replacement, prefix_size, suffix_size, acc) when prefix_size >= 0 do
716716
case string do
717-
<<prefix::size(prefix_size)-binary, suffix::size(suffix_size)-binary>> when suffix == match ->
717+
<<prefix::size(prefix_size)-binary, suffix::binary>> when suffix == match ->
718718
replace_trailing(prefix, match, replacement, prefix_size - suffix_size, suffix_size, acc + 1)
719719
_ ->
720-
string <> duplicate(replacement, acc)
720+
append_unless_empty(string, duplicate(replacement, acc))
721721
end
722722
end
723723

724724
defp replace_trailing(string, _match, replacement, _prefix_size, _suffix_size, acc) do
725-
string <> duplicate(replacement, acc)
725+
append_unless_empty(string, duplicate(replacement, acc))
726726
end
727727

728728
@doc """
@@ -755,11 +755,10 @@ defmodule String do
755755
def replace_prefix(string, match, replacement)
756756
when is_binary(string) and is_binary(match) and is_binary(replacement) do
757757
prefix_size = byte_size(match)
758-
suffix_size = byte_size(string) - prefix_size
759758

760759
case string do
761-
<<prefix::size(prefix_size)-binary, suffix::size(suffix_size)-binary>> when prefix == match ->
762-
replacement <> suffix
760+
<<prefix::size(prefix_size)-binary, suffix::binary>> when prefix == match ->
761+
prepend_unless_empty(replacement, suffix)
763762
_ ->
764763
string
765764
end
@@ -798,13 +797,21 @@ defmodule String do
798797
prefix_size = byte_size(string) - suffix_size
799798

800799
case string do
801-
<<prefix::size(prefix_size)-binary, suffix::size(suffix_size)-binary>> when suffix == match ->
802-
prefix <> replacement
800+
<<prefix::size(prefix_size)-binary, suffix::binary>> when suffix == match ->
801+
append_unless_empty(prefix, replacement)
803802
_ ->
804803
string
805804
end
806805
end
807806

807+
@compile {:inline, prepend_unless_empty: 2, append_unless_empty: 2}
808+
809+
defp prepend_unless_empty("", suffix), do: suffix
810+
defp prepend_unless_empty(prefix, suffix), do: prefix <> suffix
811+
812+
defp append_unless_empty(prefix, ""), do: prefix
813+
defp append_unless_empty(prefix, suffix), do: prefix <> suffix
814+
808815
@doc false
809816
# TODO: Remove by 2.0
810817
# (hard-deprecated in elixir_dispatch)

0 commit comments

Comments
 (0)