diff options
author | Michał Muskała <michal@muskala.eu> | 2018-04-24 19:21:57 +0200 |
---|---|---|
committer | Michał Muskała <michal@muskala.eu> | 2018-04-30 13:09:57 +0200 |
commit | 18fd5a685512868fd37229e5f8e43b0fa210c667 (patch) | |
tree | 340f418a64b7e439decac921230906c0bf9f5c3e | |
parent | 14fd1d31ed86b390404db0c67683af0fa93424c3 (diff) | |
download | elixir-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.ex | 25 |
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 """ |