Skip to content
This repository

crystalizer--it takes your ruby code and crystalizes it into a much faster form by c-ifying it (originally based off ruby2cext code). Can result in up to 5X the speed of 1.9

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 benchmarks
Octocat-spinner-32 bin
Octocat-spinner-32 doc
Octocat-spinner-32 lib
Octocat-spinner-32 stuff
Octocat-spinner-32 test
Octocat-spinner-32 Changelog
Octocat-spinner-32 README
Octocat-spinner-32 Rakefile
Octocat-spinner-32 TODO
Octocat-spinner-32 VERSION
Octocat-spinner-32 results
Octocat-spinner-32 setup.rb
README
----------- Crystalizer -------------

The crystalizer gem is basically a "user friendly" wrapper for a ruby2c converter called ruby2cext.  It takes your ruby code, creates its rubyC equivalent, and replaces the existing ruby methods with their C "optimized" equivalents, effectively JIT-ing existing Ruby code.  

It is called crystalizer because you create your code first in ruby, then "crystalize" it to C.  It also does call location cacheing, thus it is crystalizing the method call lookups so they can be done in C instead of Ruby, making it faster.

It currently uses most of the optional optimizations that ruby2cext provides, to try and squeeze out as much speed as possible.

On some artificial benchmarks, it has run at up to 5x the speed of 1.9 (http://github.com/rdp/crystalizer/blob/master/results), though it's unclear if it actually provides any speedup in the real world, over 1.9.  If not then updating it to be 1.9 compatible might do the trick.

---- Usage ----

require 'concretizer'

Klass.concretize! # concretizes all interior methods of this class, and methods of its ancestors

or, if you have several classes and don't want to have to remember exactly which ones to concretize, you can pass it a block.

Ruby2CExtension::Concretize.crystalize_after_first_time_through {
    # do some stuff here
    # after completing this block, it will concretize any and all classes run within the block
    # so the first time through will slower than usual, and second and third times should be faster [or any other code that subsequently calls those classes]
    # still a bit buggy
}

And for the daring, concretize all classes thus:

Ruby2CExtension::Conretize.concretize_all!  # crystalizes all existing classes -- takes forever, you might discover bugs in edge cases that aren't covered yet--but should speed up everything, and it does pass its unit tests, at least.  Report bugs back to me.

Also an option is the included rb2cx executable
$ rb2cx ruby_filename.rb

which creates ruby_filename.{c, so} based on ruby_filename.rb.

Thus you could run the ruby script's c equivalent thus:
$ ruby -rruby_filename.so -e ''

or with optimizations turned on:
$ rb2cx ruby_filename.rb -O all


Currently the safest/sanest way is to use rb2cx to convert a single file into C, then use that file's .so

Caveats:

Some of the optimizations make some speed-up enabling assumptions (like that you won't be overwriting any constants [you don't anyway, right?], and won't be overwriting defined methods).  It therefore isn't 100% pure ruby compatible, and it also loses backtrace information (though there is an option to turn on some backtrace info--it is quite faster without it).  It has thus proven quite a bit faster than 1.9 in some benchmarks, though it is currently a 1.8 only library [presumably if it were made 1.9 compatible, it might be even faster, because the stdlib for 1.9 seems to be faster].

Crystalize only crystalizes methods--it doesn't crystalize proc objects in the system--they stay as pure Ruby--it does crystalize procs created from within crystalized methods, though, which is typically probably good enough. 

Note that you will need the rubynode gem, see below.

Also note: not 1.9 compat. currently, though this is probably a high-ish priority, should I ever want more speed than it currently gives :).  Should it ever become so, you may want to cache your eval'ed methods, so that they can be optimized [only methods from a real file can be found again, and optimized].

Usages:
You could theoretically use this to crystalize slow parts of your code, or a gem packager could even distribute a "pure ruby" and "crystalized" version of their code, let your imagination go wild.


Feedback welcome: http://github.com/rdp/crystalizer

If you have a special use case ["I use int's a lot for mandelbrot!"] or what not let me know--I might be able to optimize crystalizer to accomodate for it [by inlining math, etc.]


Speed notes:  Using local variables are much faster, after which in speed is (I think) using constants, then instance variables (i.e. instance variables can be slow, if you're looking for raw speed).  You may be able to use and get some speed up if you can use constants instead of instance variables...

Ex:
A = {}

def go
 A.clear
  # do some stuff with A, as long as you're single threaded and can leave it at the end.
end

Though I haven't speed tested this hypothesis yet.


Much thanks to the original author of Ruby2CExtension, since this is only a wrapper to his work, basically, with some minor changes.

Mailing list: http://groups.google.com/group/ruby-optimization


Ruby2CExtension (begin original README)...
===============

Ruby2CExtension is a Ruby to C extension translator/compiler. It takes any Ruby
source file, parses it using Ruby's builtin parser and then translates the
abstract syntax tree into "equivalent" C extension code.


Requirements
------------

* Ruby 1.8.4, 1.8.5 or 1.8.6 (possibly 1.8.7--haven't tried)
* RubyNode (available at http://rubynode.rubyforge.org/) 


Installation
------------

Just run (as root): TODO make this easier

  gem install ruby2cext
  # you may need to download the source files for your ruby distro--follow instructions if gem install failure

Documentation
-------------

Please see doc/index.html for more documentation.




License
-------

Copyright 2006-2007 Dominik Bathon <dbatml@gmx.de>

Ruby2CExtension is licensed under the same terms as Ruby.

Something went wrong with that request. Please try again.