Instantly share code, notes, and snippets.

@zarqman /geoip.rb
Last active Jul 24, 2018

Embed
What would you like to do?
Benchmark various GeoIP gems
# Related blog post: https://iprog.com/posting/2017/10/benchmarking-geoip-gems
require 'benchmark'
PASS = 1 # 1 or 2
### libraries for C extensions
# brew install geoip
# brew install libmaxminddb
### geoip data db's
# curl -o http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
# curl -o http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.tar.gz
### geoip1 (legacy)
if PASS==1
# gem install geoip io-extra
require 'geoip'
db1 = GeoIP.new('./GeoLiteCity.dat', preload: false)
# preload loads whole file as a StringIO
db1p = GeoIP.new('./GeoLiteCity.dat', preload: true)
end
if PASS==2
# gem install geoip-c
require 'geoip'
# _must_ uninstall the 'geoip' gem first, else require() loads that gem, not geoip-c
db7 = GeoIP::City.new('./GeoLiteCity.dat')
end
### geoip2
if PASS==1
# gem install maxminddb
require 'maxminddb'
db2 = MaxMindDB.new('./GeoLite2-City.mmdb')
# gem install geoip2_compat
require 'geoip2_compat'
db3 = GeoIP2Compat.new('./GeoLite2-City.mmdb')
# gem install hive_geoip2
require 'hive_geoip2'
db4 = Hive::GeoIP2.new('./GeoLite2-City.mmdb')
# gem install maxmind_geoip2
require 'maxmind_geoip2'
MaxmindGeoIP2.file('./GeoLite2-City.mmdb')
MaxmindGeoIP2.locale 'en'
end
if PASS==2
# gem install mmdb
require 'mmdb'
db6 = MaxMindDB.new('./GeoLite2-City.mmdb')
end
COUNT = 100_000
ip_set = COUNT.times.map{ "#{rand(223)+1}.#{rand(256)}.#{rand(256)}.#{rand(256)}" }
Benchmark.bm(25) do |x|
if PASS==1
x.report('geoip (1;rb)') do
COUNT.times do |n|
ip = ip_set[n]
res = db1.city(ip)
if res
[res.country_code2, res.real_region_name, res.timezone]
end
end
end
x.report('geoip (1;rb;preload)') do
COUNT.times do |n|
ip = ip_set[n]
res = db1p.city(ip)
if res
[res.country_code2, res.real_region_name, res.timezone]
end
end
end
end
if PASS==2
x.report('geoip-c (1;c) -tz') do
COUNT.times do |n|
ip = ip_set[n]
res = db7.look_up(ip)
if res
[res[:country_code], res[:region_name], "no-timezone"]
end
end
end
end
if PASS==1
x.report('maxminddb (2;rb)') do
COUNT.times do |n|
ip = ip_set[n]
res = db2.lookup(ip)
if res.found?
[res.country.iso_code, res.subdivisions[0] && res.subdivisions[0].name, res.location.time_zone]
end
end
end
x.report('geoip2_compat (2;c) -tz') do
COUNT.times do |n|
ip = ip_set[n]
res = db3.lookup(ip) ; nil
if res
[res[:country_code], res[:region_name], "no-timezone"]
end
end
end
x.report('hive_geoip2 (2;c)') do
COUNT.times do |n|
ip = ip_set[n]
res = db4.lookup(ip) ; nil
if res
begin
[res['country'] && res['country']['iso_code'], res['subdivisions'] && res['subdivisions'][0] && res['subdivisions'][0]['names']['en'], res['location'] && res['location']['time_zone']]
rescue
puts res ; raise
end
end
end
end
x.report('maxmind_geoip2 (2;c)') do
COUNT.times do |n|
ip = ip_set[n]
res = MaxmindGeoIP2.locate(ip) ; nil
if res
[res['country_code'], res['subdivision'], res['time_zone']]
end
end
end
end
if PASS==2
x.report('mmdb (2;c) -tz') do
COUNT.times do |n|
ip = ip_set[n]
res = db6.lookup(ip) ; nil
if res
[res[:country_code], res[:subdivisions] && res[:subdivisions][0], "no-timezone"]
end
end
end
end
end
# (c) 2017 t.e.morgan
# Licensed under the Creative Commons Attribution 4.0 International License
# http://creativecommons.org/licenses/by/4.0/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment