--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--