Skip to content

Instantly share code, notes, and snippets.

@stevegrossi
Last active July 21, 2017 14:17
Show Gist options
  • Save stevegrossi/bbca6678f610562d5048415e42f59fe7 to your computer and use it in GitHub Desktop.
Save stevegrossi/bbca6678f610562d5048415e42f59fe7 to your computer and use it in GitHub Desktop.
Elixir parsing stringy integers: rescue vs. regex
defmodule StringToIntegerBench do
use Benchfella
@word "string"
@integer "1234"
bench "regex for word" do
if numeric_string?(@word) do
@word |> String.to_integer
else
@word
end
end
bench "regex for integer" do
if numeric_string?(@integer) do
@integer |> String.to_integer
else
@integer
end
end
bench "rescue for word" do
try do
String.to_integer(@word)
rescue
_ in ArgumentError -> @word
end
end
bench "rescue for integer" do
try do
String.to_integer(@integer)
rescue
_ in ArgumentError -> @integer
end
end
defp numeric_string?(string) do
Regex.match?(~r/\A\d+\Z/, string)
end
end
@stevegrossi
Copy link
Author

Results: try/rescue wins by far. This surprised me coming from Ruby where exceptions are extremely expensive.

# benchmark name      iterations   average time
# rescue for integer  1000000000   0.01 µs/op
# rescue for word      100000000   0.08 µs/op
# regex for word        10000000   0.75 µs/op
# regex for integer     10000000   0.94 µs/op

I wondered if extracting the regex into a module attribute would speed up its parsing, but of course Elixir is compiled so the regex isn't parsed at runtime and it doesn't make any difference:

# ## StringToIntegerBench
# benchmark name             iterations   average time
# regex inline                 10000000   0.74 µs/op
# regex in module attribute    10000000   0.74 µs/op

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment