--gr/z0/N6AeWAPJVB
Content-Type: multipart/mixed; boundary="IrhDeMKUP4DT/M7F"
Content-Disposition: inline
--IrhDeMKUP4DT/M7F
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
I starting to dip my toes in non-Ruby coding (for performance reasons)
and began with looking at the (simplest) choice of Ruby Inline.
Interestingly, while my own number-crunching code seems to be generally
three times faster in Ruby 1.9 than in Ruby 1.8, the attached script
a slightly altered Corey Hoffstein¡Çs example seems to be actually
running its Ruby part slightly slower under Ruby 1.9, and over two times
slower when it comes to its C part:
$ ruby -v sort.rb; ruby sort.rb; ruby sort.rb
ruby 1.8.7 (2009-09-11 patchlevel 202) [x86_64-linux]
Ruby Time: 68.987515
Inline Time: 7.591179
Ruby Time: 67.758257
Inline Time: 7.371522
Ruby Time: 68.420539
Inline Time: 7.361452
$ ruby -v sort.rb; ruby sort.rb; ruby sort.rb
ruby 1.9.1p243 (2009-07-16) [x86_64-linux]
Ruby Time: 80.945370503
Inline Time: 17.813790662
Ruby Time: 75.493231541
Inline Time: 16.430632733
Ruby Time: 74.406748965
Inline Time: 17.018331102
What could be the culprit of this speed difference?
(Note that the C part is using the C++ Boost library but I doubt this
matters much, as the code is the same in both cases, and the resulting
.so file seems to be interchaneable between the two Ruby versions.)
http://coreyhoffstein.com/2009/06/16/sorting-with-ruby-rubyinline-and-thrust/
¡½ Shot
--
ruby.about.com thinks ¡Ætrollop¡Ç is an inappropriate
name for a gem? Wait till they meet me in person.
[William Morgan]
--IrhDeMKUP4DT/M7F
Content-Type: application/x-ruby
Content-Disposition: attachment; filename="sort.rb"
Content-Transfer-Encoding: quoted-printable
# Ruby Sort Neighbors example
# Take N random (x,y) points
# For eachoint, sort the neighbors!
require 'rubygems'
require 'inline'
N = 1_000
class Point
attr_accessor :x, :y
def initialize(x, y)
@x = x
@y = y
end
def distance(other)
Math.sqrt((other.x - @x)**2 + (other.y - @y)**2)
end
end
def find_nearest_neighbors(point, neighbors)
return neighbors.sort { |a,b| point.distance(a) <=> point.distance(b) }
end
class NearestNeighbor
inline(:C) do |builder|
builder.add_compile_flags '-x c++',-lstdc++', '-I/usr/local/include/boost-1_39/'
builder.include '<algorithm>'
builder.include '<vector>'
builder.include '<boost/bind.hpp>'
builder.include '<cmath>'
builder.prefix '
int distance(VALUE a, VALUE b, VALUE c) {
double a_x = NUM2DBL(rb_iv_get(a, "@x"));
double a_y = NUM2DBL(rb_iv_get(a, "@y"));
double b_x = NUM2DBL(rb_iv_get(b, "@x"));
double b_y3D NUM2DBL(rb_iv_get(b, "@y"));
double c_x = NUM2DBL(rb_iv_get(c, "@x"));
double c_y = NUM2DBL(rb_iv_get(c, "@y"));
ouble b_dist = sqrt(pow(b_x-a_x, 2) + pow(b_y-a_y, 2));
double c_dist = sqrt(pow(c_x-a_x, 2) + pow(c_y-a_y, 2));
return (b_dist < c_dist);
}
'
builder.c '
VALUE find_nearest_neighbors(VALUE point, VALUE neighbors) {
const VALUE *base = RARRAY_PTR(neighbors);
std::vector<VALUE> sorted_neighbors(base, base + RARRAY_LEN(neighbors));
std::sort(sorted_neighbors.begin(), sorted_neighbors.end(), boost::bind(&distance, point, _1, _2));
return rb_ary_new4(RARRAY_LEN(neighbors), &sorted_neighbors.front());
}
'
end
end
# initialize our points
points = []
N.times {
points << Point.new(rand, rand)
}
nearest_neighbors = []
start = Time.now
points.each_index { |i|
nearest_neighbors[i] = find_nearest_neighbors(points[i], points[0...i] + points[i+1..(N-1)])
}
finish = Time.now
puts "Ruby Time: #{finish-start}"
nearest_neighbors_inline = []
nn = NearestNeighbor.new()
start = Time.now
points.each_index { |i|
nearest_neighbors_inline[i] = nn.find_nearest_neighbors(points[i], points[0...i] + points[i+1..(N-1)])
}
finish = Time.now
puts "Inline Time: #{finish-start}"
--IrhDeMKUP4DT/M7F--
--gr/z0/N6AeWAPJVB
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: Digital signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
iEYEARECAAYFAkrwJjUACgkQi/mCfdEo8Uo0tQCgx3E6GUal7SKL+JskB84lN3nP
XSoAn3xRq2SpjWyOZOaSBwOOh58gtmJM
g1
-----END PGP SIGNATURE-----
--gr/z0/N6AeWAPJVB--