Skip to content

Instantly share code, notes, and snippets.

@charliedavi
Created April 6, 2012 14:59
Show Gist options
  • Save charliedavi/2320597 to your computer and use it in GitHub Desktop.
Save charliedavi/2320597 to your computer and use it in GitHub Desktop.
Firstly I know that having a C extension in JRUBY is not a great idea, however, I am kind of being forced in a way.
I have a system at the moment that uses a Ruby KDTree https://github.com/MagLev/maglev/tree/master/examples/persistence/kdtree/
It works, but its not very quick. I am using Jruby because of its great performance and would love to stay with it.
To improve the speed of the KDTree, I found and used https://github.com/consti/tupalo-kdtree which is crazy quick, it also has the same syntax for use http://rubydoc.info/gems/tupalo-kdtree/0.2.3/frames and it works great under MRI 1.9.3 - it brings down on benchmark from 30 seconds to around 0.01 seconds.
However when I try and load this gem in Jruby it only works to load using JRUBY_OPTS=--1.8 - which is odd, but it loads find and installs.
However when I run the attached code, it runs incredibly slow. unless you decrease the number of objects going into the KDTree - almost as if it runs out of memory?
require 'rubygems'
require "benchmark"
gem 'tupalo-kdtree'
require 'kdtree'
#set the number of lat/lngs to go into KDTree
@kdsize = 10000000
# sets up random lat longs and loads them into the KDTree - len = number of lat/lngs
def setup_tree(len)
@points = (0...len).map { |i| [rand_coord, rand_coord, i ] }
@kdtree = KDTree.new(@points)
end
# little method to generate random lat/lngs
def rand_coord
rand(0) * 10 - 5
end
# looks up random lat long to find nearest neighbour inside KDTree
def test_nearestk
pt = []
@list = []
2000.times do
pt = [rand_coord, rand_coord]
@list << @kdtree.nearest(pt[0],pt[1])
end
end
#create KDTree (takes the longest)
setup_tree(@kdsize)
#Benchmark the time it takes to lookup @list for nearest neighboard in @kdtree
Benchmark.bm do |x|
x.report do
test_nearestk
end
end
If you change @kdsize to 1000 it works pretty well!
I do not know why this doesn't run will inside of Jruby, and if it is a really stupid idea can someone think of an alternative? I am a bit stuck! But would love to get away from the 30 seconds it takes to run the original ruby code and use the C code.
This is my first post in here, sorry if it is too much!
Thanks Charlie
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment