Skip to content

Instantly share code, notes, and snippets.

@hauleth
Created March 27, 2025 16:23
Show Gist options
  • Save hauleth/1d8ae294042e54d86fef60c489c822bb to your computer and use it in GitHub Desktop.
Save hauleth/1d8ae294042e54d86fef60c489c822bb to your computer and use it in GitHub Desktop.

Last part benchmark

Mix.install([
  {:benchee, "~> 1.0"},
  {:kino_benchee, "~> 0.1.0"},
  {:faker, "~> 0.18"}
])

Benchmark Definitions

defmodule StringExt do
  defguardp is_ending_with(str, pat) when binary_part(str, byte_size(str), -byte_size(pat)) == pat
  
  def rsplit(string, pattern), do: do_rsplit(string, pattern, "")

  defp do_rsplit("", _pat, acc), do: ["", acc]
  defp do_rsplit(str, pat, acc) when is_ending_with(str, pat), do: [binary_part(str, 0, byte_size(str)-byte_size(pat)), acc]
  defp do_rsplit(str, pat, acc) do
    <<front::binary-size(byte_size(str) - 1), c>> = str
    do_rsplit(front, pat, <<c>> <> acc)
  end
end
defmodule Benchmarks do 
  def string_split_list_last(input) do
    input |> String.split("_") |> List.last()
  end

  @pattern ~r/([^_]*)$/
  
  def regex(input) do
    case Regex.run(@pattern, input, capture: :first) do
      [a] -> a
      _ -> ""
    end
  end

  def split_trailing(input) do
    case :string.split(input, "_", :trailing) do
      [a] -> a
      [_, a] -> a
    end
  end

  def rsplit(input) do
    [_, a] = StringExt.rsplit(input, "_")

    a
  end
end

Benchmark Results

Benchee.run(
  %{
    "String.split |> List.last" => &Benchmarks.string_split_list_last/1,
    "Regex.run |> List.first" => &Benchmarks.regex/1,
    ":string.split(_, _, :trailing)" => &Benchmarks.split_trailing/1,
    "StringExt.rsplit()" => &Benchmarks.rsplit/1
  },
  inputs: %{
    "empty" => "",
    "none" => Faker.Lorem.word(),
    "small" => Enum.map_join(1..10, "_", fn _ -> Faker.Lorem.word() end),
    "medium" => Enum.map_join(1..1000, "_", fn _ -> Faker.Lorem.word() end),
    "large" => Enum.map_join(1..100000, "_", fn _ -> Faker.Lorem.word() end)
  }
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment