Skip to content

Commit 4b795a0

Browse files
author
José Valim
committed
Optimize downcase, upcase and rstrip in Unicode
1 parent c80e52e commit 4b795a0

File tree

2 files changed

+34
-22
lines changed

2 files changed

+34
-22
lines changed

lib/elixir/lib/string.ex

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,9 @@ defmodule String do
208208
209209
"""
210210
@spec upcase(t) :: t
211-
defdelegate upcase(binary), to: String.Unicode
211+
def upcase(binary) do
212+
String.Unicode.upcase(binary, [])
213+
end
212214

213215
@doc """
214216
Convert all characters on the given string to downcase.
@@ -224,7 +226,9 @@ defmodule String do
224226
225227
"""
226228
@spec downcase(t) :: t
227-
defdelegate downcase(binary), to: String.Unicode
229+
def downcase(binary) do
230+
String.Unicode.downcase(binary, [])
231+
end
228232

229233
@doc """
230234
Converts the first character in the given string to

lib/elixir/priv/unicode.ex

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -57,32 +57,36 @@ defmodule String.Unicode do
5757

5858
# Downcase
5959

60-
def downcase(""), do: ""
61-
6260
lc { codepoint, _upper, lower, _title } inlist codes, lower && lower != codepoint do
63-
def downcase(unquote(codepoint) <> rest) do
64-
unquote(lower) <> downcase(rest)
61+
l = binary_to_list(lower) |> :lists.reverse
62+
63+
def downcase(unquote(codepoint) <> rest, acc) do
64+
downcase(rest, unquote(l) ++ acc)
6565
end
6666
end
6767

68-
def downcase(<< char, rest :: binary >>) do
69-
<< char >> <> downcase(rest)
68+
def downcase(<< char, rest :: binary >>, acc) do
69+
downcase(rest, [char|acc])
7070
end
7171

72-
# Upcase
72+
def downcase("", acc), do: acc |> :lists.reverse |> list_to_binary
7373

74-
def upcase(""), do: ""
74+
# Upcase
7575

7676
lc { codepoint, upper, _lower, _title } inlist codes, upper && upper != codepoint do
77-
def upcase(unquote(codepoint) <> rest) do
78-
unquote(upper) <> upcase(rest)
77+
u = binary_to_list(upper) |> :lists.reverse
78+
79+
def upcase(unquote(codepoint) <> rest, acc) do
80+
upcase(rest, unquote(u) ++ acc)
7981
end
8082
end
8183

82-
def upcase(<< char, rest :: binary >>) do
83-
<< char >> <> upcase(rest)
84+
def upcase(<< char, rest :: binary >>, acc) do
85+
upcase(rest, [char|acc])
8486
end
8587

88+
def upcase("", acc), do: acc |> :lists.reverse |> list_to_binary
89+
8690
# Titlecase once
8791

8892
def titlecase_once(""), do: { "", "" }
@@ -109,23 +113,27 @@ defmodule String.Unicode do
109113

110114
def lstrip(other) when is_binary(other), do: other
111115

112-
def rstrip(""), do: ""
113-
114116
def rstrip(string) when is_binary(string) do
115-
do_rstrip(string, "")
117+
do_rstrip(string, [], [])
116118
end
117119

118120
lc codepoint inlist whitespace do
119-
defp do_rstrip(unquote(codepoint) <> rest, buffer) do
120-
do_rstrip(rest, unquote(codepoint) <> buffer)
121+
c = binary_to_list(codepoint) |> :lists.reverse
122+
123+
defp do_rstrip(unquote(codepoint) <> rest, acc1, acc2) do
124+
do_rstrip(rest, unquote(c) ++ (acc1 || acc2), acc2)
121125
end
122126
end
123127

124-
defp do_rstrip(<< char, rest :: binary >>, buffer) do
125-
<< buffer :: binary, char, do_rstrip(rest, "") :: binary >>
128+
defp do_rstrip(<< char, rest :: binary >>, nil, acc2) do
129+
do_rstrip(rest, nil, [char|acc2])
130+
end
131+
132+
defp do_rstrip(<< char, rest :: binary >>, acc1, _acc2) do
133+
do_rstrip(rest, nil, [char|acc1])
126134
end
127135

128-
defp do_rstrip(<<>>, _), do: <<>>
136+
defp do_rstrip(<<>>, _acc1, acc2), do: acc2 |> :lists.reverse |> list_to_binary
129137

130138
# Split
131139

0 commit comments

Comments
 (0)