summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Muskała <michal@muskala.eu>2018-04-24 19:21:57 +0200
committerMichał Muskała <michal@muskala.eu>2018-04-30 13:09:57 +0200
commit18fd5a685512868fd37229e5f8e43b0fa210c667 (patch)
tree340f418a64b7e439decac921230906c0bf9f5c3e
parent14fd1d31ed86b390404db0c67683af0fa93424c3 (diff)
downloadelixir-mm/string-ends-with-optim.tar.gz
Optimise String.ends_with?/2mm/string-ends-with-optim
The new implementation is 10-70 times faster on the benchmark data. Full benchmark: https://gist.github.com/michalmuskala/74ebb0456c8cfbfe8e012ce4aae2b6e5
-rw-r--r--lib/elixir/lib/string.ex25
1 files changed, 13 insertions, 12 deletions
diff --git a/lib/elixir/lib/string.ex b/lib/elixir/lib/string.ex
index 007fcd33b..428bb05c3 100644
--- a/lib/elixir/lib/string.ex
+++ b/lib/elixir/lib/string.ex
@@ -1933,23 +1933,24 @@ defmodule String do
"""
@spec ends_with?(t, t | [t]) :: boolean
- def ends_with?(string, suffixes) when is_binary(string) and is_list(suffixes) do
- Enum.any?(suffixes, &do_ends_with(string, &1))
+ def ends_with?(string, suffix) when is_binary(string) and is_binary(suffix) do
+ ends_with_string?(string, byte_size(string), suffix)
end
- def ends_with?(string, suffix) when is_binary(string) do
- do_ends_with(string, suffix)
- end
-
- defp do_ends_with(_string, "") do
- true
+ def ends_with?(string, suffix) when is_binary(string) and is_list(suffix) do
+ string_size = byte_size(string)
+ Enum.any?(suffix, &ends_with_string?(string, string_size, &1))
end
- defp do_ends_with(string, suffix) when is_binary(suffix) do
- string_size = byte_size(string)
+ @compile {:inline, ends_with_string?: 3}
+ defp ends_with_string?(string, string_size, suffix) when is_binary(suffix) do
suffix_size = byte_size(suffix)
- scope = {string_size - suffix_size, suffix_size}
- suffix_size <= string_size and :nomatch != :binary.match(string, suffix, scope: scope)
+
+ if suffix_size <= string_size do
+ suffix == binary_part(string, string_size - suffix_size, suffix_size)
+ else
+ false
+ end
end
@doc """