Browse | Submit A New Snippet | Create A Package

 

Date/Rational/Fixnum#gcd hack increased performance by 15%

Type:
Function
Category:
Math Functions
License:
GNU General Public License
Language:
Ruby
 
Description:

Date uses Rational heavily, which calls Integer#gcd for every new Rational. The Integer#gcd method is generic to handle Bignums, but performs terribly for Fixnum#gcd(Fixnum), which is probably the most often case.

My RubyInline hack saved 15% execution time in a large Rails application:

Versions Of This Snippet::

Kurt Stephens
Snippet ID Download Version Date Posted Author Delete
2070.0.12007-03-29 04:28Kurt Stephens

Download a raw-text version of this code by clicking on "Download Version"

 


Latest Snippet Version: :0.0.1

# See http://kurtstephens.com/node/34

require 'inline'

class Fixnum
  inline do | builder |
    builder.c_raw '
    static
    VALUE 
    gcd(int argc, VALUE *argv, VALUE self) {
      if ( argc != 1 ) {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 1);
      }
      /* Handle Fixnum#gcd(Fixnum) case directly. */
      if ( FIXNUM_P(argv[0]) ) {
        /* fprintf(stderr, "Using Fixnum#gcd(Fixnum)\n"); */
        long a = FIX2LONG(self);
        long b = FIX2LONG(argv[0]);
        long min = a < 0 ? - a : a;
        long max = b < 0 ? - b : b;
        while ( min > 0 ) {
          int tmp = min;
          min = max % min;
          max = tmp;
        }
        return LONG2FIX(max);
      } else {
        /* fprintf(stderr, "Using super#gcd\n"); */
        return rb_call_super(1, argv);
      }
    }
    '
  end
end
		

Submit a new version

You can submit a new version of this snippet if you have modified it and you feel it is appropriate to share with others..