Skip to content

Commit 3c7fb0d

Browse files
author
José Valim
committed
Optimize split implementation
1 parent 89bebea commit 3c7fb0d

File tree

3 files changed

+30
-29
lines changed

3 files changed

+30
-29
lines changed

lib/elixir/lib/regex.ex

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ defmodule Regex do
152152
[foo: "d"]
153153
iex> Regex.captures(%r/a(?<foo>b)c(?<bar>d)/g, "abcd")
154154
[foo: "b", bar: "d"]
155-
iex> Regex.captures(%r/a(?<foo>b)c(?<bar>d)/g, "efgh")
155+
iex> Regex.captures(%r/a(?<foo>b)c(?<bar>d)/g, "efgh")
156156
nil
157157
158158
"""
@@ -257,24 +257,29 @@ defmodule Regex do
257257
["a","b","c"]
258258
iex> Regex.split(%r/-/, "a-b-c", [parts: 2])
259259
["a","b-c"]
260-
iex> Regex.split(%r/-/, "abc")
260+
iex> Regex.split(%r/-/, "abc")
261261
["abc"]
262262
"""
263263

264264
def split(regex, string, options // [])
265265

266266
def split(regex(re_pattern: compiled), string, options) do
267-
defaults = [global: true, trim: true, parts: :infinity, return: return_for(string)]
268-
options = Keyword.merge(defaults, options)
269-
270-
unless options[:global], do: options = Keyword.put(options, :parts, 2)
271-
272-
valid_options = Dict.take(options, [:parts, :return])
273-
splits = :re.split(string, compiled, valid_options)
267+
parts =
268+
cond do
269+
Keyword.get(options, :global) == false -> 2
270+
p = Keyword.get(options, :parts) -> p
271+
true -> :infinity
272+
end
274273

275-
if options[:trim], do: splits = Enum.filter(splits, &(&1 != ""))
274+
return = Keyword.get(options, :return, return_for(string))
275+
opts = [return: return, parts: parts]
276+
splits = :re.split(string, compiled, opts)
276277

277-
splits
278+
if Keyword.get(options, :trim, true) do
279+
lc split inlist splits, split != "", do: split
280+
else
281+
splits
282+
end
278283
end
279284

280285
@doc %B"""

lib/elixir/lib/string.ex

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,14 @@ defmodule String do
197197
end
198198

199199
def split(binary, pattern, options) do
200-
defaults = [global: true, trim: true]
201-
options = Keyword.merge(defaults, options)
202-
203-
option_keys = Enum.filter_map(options, &elem(&1, 1), &elem(&1, 0))
204-
splits = :binary.split(binary, pattern, option_keys)
205-
206-
if options[:trim], do: splits = Enum.filter(splits, &(&1 != ""))
200+
opts = if options[:global] != false, do: [:global], else: []
201+
splits = :binary.split(binary, pattern, opts)
207202

208-
splits
203+
if Keyword.get(options, :trim, true) do
204+
lc split inlist splits, split != "", do: split
205+
else
206+
splits
207+
end
209208
end
210209

211210
@doc """

lib/elixir/priv/unicode.ex

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,7 @@ defmodule String.Unicode do
145145

146146
lc codepoint inlist whitespace do
147147
defp do_split(unquote(codepoint) <> rest, buffer, acc) do
148-
if buffer != "" do
149-
do_split(rest, "", [buffer | acc])
150-
else
151-
do_split(rest, buffer, acc)
152-
end
148+
do_split(rest, "", add_buffer_to_acc(buffer, acc))
153149
end
154150
end
155151

@@ -158,13 +154,14 @@ defmodule String.Unicode do
158154
end
159155

160156
defp do_split(<<>>, buffer, acc) do
161-
if buffer != "" do
162-
[buffer | acc]
163-
else
164-
acc
165-
end
157+
add_buffer_to_acc(buffer, acc)
166158
end
167159

160+
@compile { :inline, add_buffer_to_acc: 2 }
161+
162+
defp add_buffer_to_acc("", acc), do: acc
163+
defp add_buffer_to_acc(buffer, acc), do: [buffer|acc]
164+
168165
# Graphemes
169166

170167
lc codepoints inlist seqs do

0 commit comments

Comments
 (0)