正木です。
色々試してみた結果 gcd,reduce,new,Rational 位を C で書けば充分みたい
なので、Tateishi さんの frac.so を参考にして、次のような 拡張 library
を書いてみました。
それ以外の method は C で書いても Ruby で書いてもそれほど違わないので、
rational.rb のものが(to_f 以外は)殆んどそのまま使えます。
(但し @numerator → numerator,@denominator → denominator)
全部を C で書けばもう少し早くなりますが、code が長くなるので省略します。

------
/*** rational.c ***/
#include "ruby.h"

VALUE
rb_num_gcd(VALUE m, VALUE n)
{
    if(FIXNUM_P(n) && FIX2INT(n)==0) return m;
    if(FIXNUM_P(m) && FIX2INT(m)==0) return n;
    return rb_num_gcd(n,rb_funcall(m,'%',1, n));
}

static VALUE
rb_math_s_gcd(VALUE self, VALUE x, VALUE y)
{
  return rb_num_gcd(x,y);
};

VALUE rb_cRational;
struct RRational
{
  VALUE num;
  VALUE den;
};

static void
rb_rational_finalizer(struct RRational *rational)
{
  /* do nothing */
};

static void
rb_rational_mark(struct RRational *rational)
{
  rb_gc_mark(rational->num);
  rb_gc_mark(rational->den);
};

VALUE
rb_rational_num(VALUE self)
{
  struct RRational *rrational;
  Data_Get_Struct(self,struct RRational, rrational);
  return rrational->num;
};

VALUE
rb_rational_den(VALUE self)
{
  struct RRational *rrational;
  Data_Get_Struct(self,struct RRational, rrational);
  return rrational->den;
};

static VALUE
rb_rational_new(VALUE self,VALUE num,VALUE den)
{
  VALUE val;
  struct RRational *rrational;
  val = Data_Make_Struct(rb_cRational,struct RRational,
			 rb_rational_mark,rb_rational_finalizer,rrational);
  rrational->num = num;
  rrational->den = den;
  return val;
};

static VALUE
rb_rational_reduce(VALUE self,VALUE num,VALUE den)
{
  VALUE g;
  if(FIXNUM_P(den) && FIX2INT(den)==0)
    rb_raise(rb_eZeroDivError,"denominator is 0");
  if(rb_funcall(den,rb_intern("<"),1, INT2FIX(0))){
    num=rb_funcall(num,rb_intern("-@"),0);
    den=rb_funcall(den,rb_intern("-@"),0);
  }
  g=rb_num_gcd(num,den);
  num=rb_funcall(num,rb_intern("div"),1, g);
  den=rb_funcall(den,rb_intern("div"),1, g);
  if(rb_funcall(den,rb_intern("=="),1, INT2FIX(1))) return num;
  return rb_rational_new(self,num,den);
};

static VALUE
rb_rational(VALUE self,VALUE num,VALUE den)
{
  return rb_rational_reduce(self,num,den);
};

void
Init_rational(void)
{
  rb_define_module_function(rb_mMath,"gcd",rb_math_s_gcd,2);
  rb_define_global_function("Rational",rb_rational,2);
  rb_cRational = rb_define_class("Rational",rb_cNumeric);
  rb_define_singleton_method(rb_cRational,"new",rb_rational_new,2);
  rb_define_singleton_method(rb_cRational,"new!",rb_rational_new,2);
  rb_define_singleton_method(rb_cRational,"reduce",rb_rational_reduce,2);
  rb_define_method(rb_cRational,"numerator",rb_rational_num,0);
  rb_define_method(rb_cRational,"denominator",rb_rational_den,0);
};
-----