Skip to content

Instantly share code, notes, and snippets.

@tneems
Created November 8, 2015 18:08
Show Gist options
  • Save tneems/b0e42dd79c8570d7e904 to your computer and use it in GitHub Desktop.
Save tneems/b0e42dd79c8570d7e904 to your computer and use it in GitHub Desktop.
RGeo vs GeoRuby benchmark
require "bundler"
Bundler.require
factory_options = {
srid: 4326,
wkt_generator: { type_format: :ewkt, emit_ewkt_srid: true, convert_case: :upper },
wkt_parser: { support_ewkt: true },
wkb_generator: { type_format: :ewkb, emit_ewkb_srid: true, hex_format: true },
wkb_parser: { support_ewkb: true }
}
ewkb = "0106000020E6100000010000000103000000010000007B0000008A247A19C53C52C07B19A88C7FA54440392861A6ED3C52C043E4D70FB1A54440865451BCCA3C52C0D826F8A6E9A54440CC237F30F03C52C0838DCEF929A64440A6EB89AE0B3D52C0455B785E2AA64440D925AAB7063D52C063DEC66647A64440876A4AB20E3D52C0CB66F16261A6444079ABAE43353D52C01895B7239CA64440B2F336363B3D52C031DFDDCA12A7444034677DCA313D52C080FB1D8A02A7444071E7C2482F3D52C039F1B8A816A74440FE428F183D3D52C0FC2284471BA744401DC70F95463D52C00BB1DD3D40A74440EB5223F4333D52C0C6DFD91EBDA74440A5F5B704E03F52C0B3629B5434A84440F1D6F9B7CB3F52C0440229B16BA94440336DFFCA4A3F52C0FC70732A19AA44408849B890473F52C056CCEB8843AA444071C45A7C0A3F52C07601124DA0AA44401BF5108DEE3E52C009DB32E02CAB444021054F21573E52C02E41295AB9AB44405F420587173E52C0AC72840CE4AB4440FB3E1C24443E52C05A61DD7877AC44406D01A1F5F03D52C06F0A0E2F88AC4440BC1DE1B4E03D52C050F2CD3637AC444036936FB6B93D52C0D760C43E01AC44409D0E643DB53D52C030DB317557AC44408B321B64923D52C0E3D9C87553AC44407407B133853D52C08789E942ACAC444084622B685A3D52C01E5CE49EAEAC4440153AAFB14B3D52C0226C5B94D9AC44405260014C193D52C09326C11BD2AC44407FD767CEFA3C52C04FE08096AEAC44402F6D382C0D3D52C0C5E3857478AC4440E4141DC9E53C52C0DB4C689258AC44406E32AA0CE33C52C042478E7406AC4440039CDEC5FB3C52C0EACBB56801AC4440C5724BAB213D52C038F564FED1AB4440486E4DBA2D3D52C0EBE38409A3AB444074BD6DA6423D52C03AD0ED258DAB4440FFCEF6E80D3D52C00F6420CF2EAB44401077F52A323C52C02AB48F15FCAA4440D11F9A79723A52C011124C35B3AA44402593533BC33952C0FF349886E1A9444025CCB4FD2B3952C03D60014C19AA4440C3F01131253952C03348A46DFCA944400D022B87163952C03699D4D006AA4440077C7E18213952C0AF7B0E2C47AA4440320395F1EF3852C0F47E86376BAA4440A48D23D6E23852C0A1DFDA8992AA4440BF0CC688443852C03269368FC3AA444037312427133852C036D1CABDC0AA444024253D0CAD3752C046423EE8D9AA44406DA818E76F3752C06E902C6002AB444016DD7A4D0F3752C05BC79BFC16AB44400F41D5E8D53752C0A899D18F86A744407F4A95287B3852C04A1A868F88A544405A9D9CA1B83852C05AB72407ECA4444003763579CA3852C00D1ADD41ECA44440E2B6B6F0BC3852C08EEE0390DAA444408A4160E5D03852C00975745C8DA44440F64201DBC13852C09ED5E59480A044405320B3B3E83852C0DFDC425722A04440CAA7C7B60C3952C037581B6327A0444004E09F52253952C0EAE21934F49F444072A3C85A433952C028CE3461FB9F4440664CC11A673952C0E045425BCE9F4440DC9F8B868C3952C06CCEA44DD59F44406C97361C963952C025394371C79F444053211E89973952C0EFB3AD669D9F4440DA3D7958A83952C01A2E55698B9F4440CECCCCCCCC3952C03502D4D4B29F44406B459BE3DC3952C043B08D78B29F4440F1F3DF83D73952C00C5D6C5A29A04440E1ED4108C83952C06C8C800A47A04440B85A272EC73952C0ED3CD4B661A04440423EE8D9AC3952C0B6C9C4AD82A044401DC9E53FA43952C02BD653ABAFA044404D64E602973952C0E1D4EAABABA044405F8429CAA53952C00D382EE3A6A044400DE02D90A03952C0FEE7137992A04440A371A8DF853952C086ED0A7DB0A044404A44F817413952C07C662C9ACEA04440CA4C69FD2D3952C0DD845E7F12A14440996379573D3952C05356B60F79A144406E675F79903952C0984D637B2DA24440766B990CC73952C0D5C9FCA36FA244408B14CAC2D73952C066A180ED60A244402E573F36C93952C0E800A43671A244409F58A7CAF73952C090F9635A9BA24440DF516342CC3952C097AE433525A34440D172A087DA3952C04A5B3FFD67A34440D6AA5D13D23952C04BB2F1608BA344407329AE2AFB3952C00D4A7B832FA444400B5D8940F53A52C07484EFFD0DA44440630B410E4A3B52C0F14DB6813BA44440A417B5FB553B52C08DD3F36E2CA44440DD5CFC6D4F3B52C0656EA12B11A4444080F3E2C4573B52C02842CD902AA4444057E883656C3B52C0306117450FA4444067B45549643B52C0B98E54DFF9A34440AD156D8E733B52C0BA30B5A50EA44440B9E00CFE7E3B52C06298F6CDFDA34440571F0F7D773B52C06CB74082E2A3444091B8C7D2873B52C0277D04FEF0A344409811DE1E843B52C04F51D845D1A34440AD69DE718A3B52C083FC4FFEEEA3444023BA675DA33B52C03BE8F527F1A3444037A45181933B52C04B02B7EEE6A3444085B2F0F5B53B52C00E7F30F0DCA34440075DC2A1B73B52C042FCDF1115A4444049111956F13B52C0DDA276BF0AA4444086E5CFB7053C52C0E5484A7A18A444404B1E4FCB0F3C52C0C570581AF8A344400838842A353C52C02FF12A6B9BA4444062804413283C52C05282E15CC3A44440D15790662C3C52C059490ED8D5A44440B41A12F7583C52C03EA86E2EFEA444401536035C903C52C0B915A58460A5444031CD74AF933C52C06225C9737DA54440F6D1A92B9F3C52C044A4897780A544408B5242B0AA3C52C04C2B685A62A544408A247A19C53C52C07B19A88C7FA54440";''
ruby_factory = RGeo::Geographic.spherical_factory(factory_options)
ffi_factory = RGeo::Geos::FFIFactory.new(factory_options)
capi_factory = RGeo::Geos.factory(factory_options)
ruby_parser = RGeo::WKRep::WKBParser.new(ruby_factory, support_ewkb: true)
ffi_parser = RGeo::WKRep::WKBParser.new(ffi_factory, support_ewkb: true)
capi_parser = RGeo::WKRep::WKBParser.new(capi_factory, support_ewkb: true)
rgeo_ruby = ruby_parser.parse(ewkb)
rgeo_ffi = ffi_parser.parse(ewkb)
rgeo_capi = capi_factory.parse_wkb(ewkb)
georuby = GeoRuby::SimpleFeatures::MultiPolygon.from_hex_ewkb ewkb
ewkt = georuby.as_ewkt
puts "ewkb parse"
Benchmark.ips do |x|
x.report("georuby ewkb parse") do
GeoRuby::SimpleFeatures::MultiPolygon.from_hex_ewkb ewkb
end
x.report("rgeo ruby ewkb parse") do
ruby_factory.parse_wkb(ewkb)
end
x.report("rgeo ffi ewkb parse") do
ffi_factory.parse_wkb(ewkb)
end
x.report("rgeo capi ewkb parse") do
capi_factory.parse_wkb(ewkb)
end
x.compare!
end
puts "=" * 80
puts "ewkb render"
Benchmark.ips do |x|
x.report("georuby ewkb render") do
georuby.as_hex_ewkb
end
x.report("rgeo ruby ewkb render") do
rgeo_ruby.as_binary
end
x.report("rgeo ffi ewkb render") do
rgeo_ffi.as_binary
end
x.report("rgeo capi ewkb render") do
rgeo_capi.as_binary
end
x.compare!
end
puts "=" * 80
puts "geojson render"
Benchmark.ips do |x|
x.report("georuby geojson render") do
georuby.as_json
end
x.report("rgeo ruby geojson render") do
RGeo::GeoJSON.encode rgeo_ruby
end
x.report("rgeo ffi geojson render") do
RGeo::GeoJSON.encode rgeo_ffi
end
x.report("rgeo capi geojson render") do
RGeo::GeoJSON.encode rgeo_capi
end
x.compare!
end
puts "=" * 80
puts "ewkt parse"
Benchmark.ips do |x|
x.report("georuby ewkt parse") do
GeoRuby::SimpleFeatures::MultiPolygon.from_ewkt ewkt
end
x.report("rgeo ruby ewkt parse") do
ruby_factory.parse_wkt(ewkt)
end
x.report("rgeo ffi ewkt parse") do
ffi_factory.parse_wkt(ewkt)
end
x.report("rgeo capi ewkt parse") do
capi_factory.parse_wkt(ewkt)
end
x.compare!
end
puts "=" * 80
puts "ewkt render"
Benchmark.ips do |x|
x.report("georuby ewkt render") do
georuby.as_ewkt
end
x.report("rgeo ruby ewkt render") do
rgeo_ruby.as_text
end
x.report("rgeo ffi ewkt render") do
rgeo_ffi.as_text
end
x.report("rgeo capi ewkt render") do
rgeo_capi.as_text
end
x.compare!
end
source 'http://rubygems.org'
gem "benchmark-ips"
gem "rgeo"
gem "ffi-geos"
gem "rgeo-shapefile"
gem "rgeo-geojson"
gem "georuby", require: "geo_ruby"
GEM
remote: http://rubygems.org/
specs:
benchmark-ips (2.3.0)
dbf (3.0.0)
ffi (1.9.10)
ffi-geos (1.1.0)
ffi (>= 1.0.0)
georuby (2.0.0)
rgeo (0.4.0)
rgeo-geojson (0.3.1)
rgeo (~> 0.3)
rgeo-shapefile (0.2.3)
dbf (>= 1.7.0)
rgeo (>= 0.3.3)
PLATFORMS
ruby
DEPENDENCIES
benchmark-ips
ffi-geos
georuby
rgeo
rgeo-geojson
rgeo-shapefile
BUNDLED WITH
1.10.6
@tneems
Copy link
Author

tneems commented Nov 8, 2015

➜  rgeo-benchmark  ruby -v
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-darwin14.0]
➜  rgeo-benchmark  ruby benchmark.rb
ewkb parse
Calculating -------------------------------------
  georuby ewkb parse   146.000  i/100ms
rgeo ruby ewkb parse    10.000  i/100ms
 rgeo ffi ewkb parse     3.000  i/100ms
rgeo capi ewkb parse    88.000  i/100ms
-------------------------------------------------
  georuby ewkb parse      1.628k (± 4.4%) i/s -      8.176k
rgeo ruby ewkb parse    111.539  (± 6.3%) i/s -    560.000 
 rgeo ffi ewkb parse     35.302  (± 2.8%) i/s -    177.000 
rgeo capi ewkb parse    854.592  (± 4.7%) i/s -      4.312k

Comparison:
  georuby ewkb parse:     1627.6 i/s
rgeo capi ewkb parse:      854.6 i/s - 1.90x slower
rgeo ruby ewkb parse:      111.5 i/s - 14.59x slower
 rgeo ffi ewkb parse:       35.3 i/s - 46.11x slower

================================================================================
ewkb render
Calculating -------------------------------------
 georuby ewkb render   572.000  i/100ms
rgeo ruby ewkb render
                         1.231k i/100ms
rgeo ffi ewkb render     7.000  i/100ms
rgeo capi ewkb render
                       316.000  i/100ms
-------------------------------------------------
 georuby ewkb render      6.179k (± 5.5%) i/s -     30.888k
rgeo ruby ewkb render
                         13.175k (± 7.9%) i/s -     66.474k
rgeo ffi ewkb render     81.284  (±14.8%) i/s -    399.000 
rgeo capi ewkb render
                          3.494k (±23.9%) i/s -     16.748k

Comparison:
rgeo ruby ewkb render:    13175.2 i/s
 georuby ewkb render:     6179.1 i/s - 2.13x slower
rgeo capi ewkb render:     3493.6 i/s - 3.77x slower
rgeo ffi ewkb render:       81.3 i/s - 162.09x slower

================================================================================
geojson render
Calculating -------------------------------------
georuby geojson render
                         2.972k i/100ms
rgeo ruby geojson render
                         1.642k i/100ms
rgeo ffi geojson render
                         7.000  i/100ms
rgeo capi geojson render
                       348.000  i/100ms
-------------------------------------------------
georuby geojson render
                         32.824k (± 4.1%) i/s -    166.432k
rgeo ruby geojson render
                         19.631k (± 4.9%) i/s -     98.520k
rgeo ffi geojson render
                         84.704  (±15.3%) i/s -    420.000 
rgeo capi geojson render
                          3.861k (±14.8%) i/s -     19.140k

Comparison:
georuby geojson render:    32823.5 i/s
rgeo ruby geojson render:    19631.5 i/s - 1.67x slower
rgeo capi geojson render:     3861.4 i/s - 8.50x slower
rgeo ffi geojson render:       84.7 i/s - 387.51x slower

================================================================================
ewkt parse
Calculating -------------------------------------
  georuby ewkt parse   103.000  i/100ms
rgeo ruby ewkt parse     9.000  i/100ms
 rgeo ffi ewkt parse     3.000  i/100ms
rgeo capi ewkt parse    41.000  i/100ms
-------------------------------------------------
  georuby ewkt parse      1.027k (± 4.2%) i/s -      5.150k
rgeo ruby ewkt parse     98.662  (± 5.1%) i/s -    495.000 
 rgeo ffi ewkt parse     38.964  (±12.8%) i/s -    192.000 
rgeo capi ewkt parse    421.624  (± 3.8%) i/s -      2.132k

Comparison:
  georuby ewkt parse:     1027.1 i/s
rgeo capi ewkt parse:      421.6 i/s - 2.44x slower
rgeo ruby ewkt parse:       98.7 i/s - 10.41x slower
 rgeo ffi ewkt parse:       39.0 i/s - 26.36x slower

================================================================================
ewkt render
Calculating -------------------------------------
 georuby ewkt render   288.000  i/100ms
rgeo ruby ewkt render
                       286.000  i/100ms
rgeo ffi ewkt render     8.000  i/100ms
rgeo capi ewkt render
                       165.000  i/100ms
-------------------------------------------------
 georuby ewkt render      2.880k (± 4.3%) i/s -     14.400k
rgeo ruby ewkt render
                          2.857k (± 4.6%) i/s -     14.300k
rgeo ffi ewkt render     83.330  (±13.2%) i/s -    416.000 
rgeo capi ewkt render
                          1.699k (±10.0%) i/s -      8.415k

Comparison:
 georuby ewkt render:     2880.2 i/s
rgeo ruby ewkt render:     2857.5 i/s - 1.01x slower
rgeo capi ewkt render:     1699.0 i/s - 1.70x slower
rgeo ffi ewkt render:       83.3 i/s - 34.56x slower

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