Created
August 8, 2016 06:17
-
-
Save paddor/2f1adbed7e42ea18a1b1ba7e1bfbe690 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "benchmark" | |
require "uri" | |
HOSTS = { | |
"fqdn" => "example.com:3000", | |
"ipv6" => "[123::1]:3000", | |
"ipv4" => "123.123.123.123:3000", | |
"mapped" => "[::192.168.1.1]:3000", | |
"garbage" => "foo.bar:a000", | |
"invalid_port" => "foo:123456", | |
"bogus" => "123::0:0", | |
"bogus2" => "123::a:0", | |
"bogus3" => "example.com:", | |
"bogus4" => "::192.168.1.1:3000", | |
} | |
def custom(input) | |
numeric?(input.at(-1)) || raise "invalid" | |
host, port = nil, nil | |
(input.size - 1).downto(0) do |i| | |
c = input.at(i) | |
if ! numeric?(c) | |
c == ':' || raise "invalid" | |
port = input[i+1 .. -1].to_i | |
raise "invalid" unless 0 < port < 2**16 | |
host = input[ 0 .. i-1] | |
# # strip "[" and "]" away | |
# host = if input.at(0) == '[' | |
# input[ 1 .. i-2] | |
# else | |
# input[ 0 .. i-1] | |
# end | |
break | |
end | |
end | |
{ host, port } | |
end | |
private def numeric?(c) | |
'0' <= c && c <= '9' | |
end | |
def regex(host) | |
m = host.match(/\A(?<host>[^:\[\]]+?|\[(?<hostipv6>.+?)\])(?::(?<port>\d+))?\z/) | |
return { nil, nil } unless m | |
#{ m["hostipv6"]? || m["host"], m["port"].to_i } # not needed because we leave "[" and "]" there | |
{ m["host"], m["port"].to_i } | |
end | |
def uri(host) | |
uri = URI.parse(host) | |
{ uri.host, uri.port } | |
end | |
puts " | |
SANITY CHECK: | |
-------------" | |
puts "nil alone means there was a parsing error" | |
HOSTS.each do |l,h| | |
puts "doing #{l} host #{h.inspect}:" | |
c, r, u = (custom(h) rescue nil), | |
(regex(h) rescue nil), | |
(uri("//#{h}") rescue nil) | |
puts " custom: #{c.inspect}" | |
puts " regex: #{r.inspect}" | |
puts " uri: #{u.inspect}" | |
next if l =~ /bogus/ | |
next if c.nil? | |
abort "mismatch (#{l}, custom<->regex)" if r && c != r | |
abort "mismatch (#{l}, custom<->uri)" if u && c != u | |
end | |
puts " | |
LOG: | |
----" | |
{% for m in %w(custom regex) %} | |
puts "{{m.id}}:" | |
{% for l,h in HOSTS %} | |
puts " {{l.id}}: #{({{m.id}}({{h}}) rescue nil).inspect}" | |
{% end %} | |
{% end %} | |
{% for m in %w(uri) %} | |
puts "{{m.id}}:" | |
{% for l,h in HOSTS %} | |
puts %{ {{l.id}}: #{({{m.id}}("//{{h.id}}") rescue nil).inspect}} | |
{% end %} | |
{% end %} | |
puts " | |
BENCHMARK: | |
----------" | |
Benchmark.ips do |x| | |
x.report("custom") do | |
{% for l in %w(fqdn ipv4 ipv6 mapped) %} | |
custom({{HOSTS[l]}}) | |
{% end %} | |
end | |
x.report("regex") do | |
{% for l in %w(fqdn ipv4 ipv6 mapped) %} | |
regex({{HOSTS[l]}}) | |
{% end %} | |
end | |
x.report("URI") do | |
{% for l in %w(fqdn ipv4 ipv6 mapped) %} | |
uri("//{{HOSTS[l].id}}") | |
{% end %} | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ crystal run --release host_port.cr | |
SANITY CHECK: | |
------------- | |
nil alone means there was a parsing error | |
doing fqdn host "example.com:3000": | |
custom: {"example.com", 3000} | |
regex: {"example.com", 3000} | |
uri: {"example.com", 3000} | |
doing ipv6 host "[123::1]:3000": | |
custom: {"[123::1]", 3000} | |
regex: {"[123::1]", 3000} | |
uri: {"[123::1]", 3000} | |
doing ipv4 host "123.123.123.123:3000": | |
custom: {"123.123.123.123", 3000} | |
regex: {"123.123.123.123", 3000} | |
uri: {"123.123.123.123", 3000} | |
doing mapped host "[::192.168.1.1]:3000": | |
custom: {"[::192.168.1.1]", 3000} | |
regex: {"[::192.168.1.1]", 3000} | |
uri: {"[::192.168.1.1]", 3000} | |
doing garbage host "foo.bar:a000": | |
custom: nil | |
regex: {nil, nil} | |
uri: nil | |
doing invalid_port host "foo:123456": | |
custom: nil | |
regex: {"foo", 123456} | |
uri: {"foo", 123456} | |
doing bogus host "123::0:0": | |
custom: nil | |
regex: {nil, nil} | |
uri: nil | |
doing bogus2 host "123::a:0": | |
custom: nil | |
regex: {nil, nil} | |
uri: nil | |
doing bogus3 host "example.com:": | |
custom: nil | |
regex: {nil, nil} | |
uri: {"example.com", 0} | |
doing bogus4 host "::192.168.1.1:3000": | |
custom: {"::192.168.1.1", 3000} | |
regex: {nil, nil} | |
uri: nil | |
LOG: | |
---- | |
custom: | |
fqdn: {"example.com", 3000} | |
ipv6: {"[123::1]", 3000} | |
ipv4: {"123.123.123.123", 3000} | |
mapped: {"[::192.168.1.1]", 3000} | |
garbage: nil | |
invalid_port: nil | |
bogus: nil | |
bogus2: nil | |
bogus3: nil | |
bogus4: {"::192.168.1.1", 3000} | |
regex: | |
fqdn: {"example.com", 3000} | |
ipv6: {"[123::1]", 3000} | |
ipv4: {"123.123.123.123", 3000} | |
mapped: {"[::192.168.1.1]", 3000} | |
garbage: {nil, nil} | |
invalid_port: {"foo", 123456} | |
bogus: {nil, nil} | |
bogus2: {nil, nil} | |
bogus3: {nil, nil} | |
bogus4: {nil, nil} | |
uri: | |
fqdn: {"example.com", 3000} | |
ipv6: {"[123::1]", 3000} | |
ipv4: {"123.123.123.123", 3000} | |
mapped: {"[::192.168.1.1]", 3000} | |
garbage: nil | |
invalid_port: {"foo", 123456} | |
bogus: nil | |
bogus2: nil | |
bogus3: {"example.com", 0} | |
bogus4: nil | |
BENCHMARK: | |
---------- | |
custom 1.84M (± 0.75%) fastest | |
regex 269.48k (± 1.23%) 6.83× slower | |
URI 1.04M (± 2.57%) 1.78× slower | |
crystal run --release host_port.cr 22.12s user 11.08s system 127% cpu 26.009 total |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment