Fastruby - fast execution of ruby code

Fastruby is a gem which allows to execute ruby code faster than normal (about 20X of the MRI1.8)

Fastruby IS NOT a separated ruby interpreter. Then, the design is simple

Fastruby IS NOT a DSL to generate C code using ruby or a Ruby to C translator, the goal of fastruby is to execute RUBY code

*************************************************************************************************************

The current version of fastruby is a Proof of Concept and it’s not ready to go to production

*************************************************************************************************************

Core Concepts

Native build

All code processed by fastruby ends with a native representation, in the current version, this is acomplished using RubyParser to parse rubycode. The ruby code is translated to C and then processed with RubyInline

Transparent multimethods (and multiblocks)

The methods processed by fastruby has multiple internal implementations depending on the type of the arguments. Each possible signature has a version of the method and this are built in runtime when the method is called with a new signature. The same concept will be applied to blocks (anonymous methods) in future releases

Type inference

Each version of a method is built for a specific signature, so, the builder can asume a type for the arguments and build method calls using that assumption. Whereever the translator can asume a type for a expression involved in a method call (used as argument or as receiver), this information can be used to encode direct calls instead of normal and expensive ruby calls.

The currently implementation only can infer types for method and block arguments, and for literals

Method inlining

Type information is used to inline methods by replacing calls with the implementation of method being called. This greatly increase the performance WITHOUT breaking the expected dynamics of ruby code (e.g. allow replace an inlined method), many of corelib methods was reimplemented with ruby to allow inline them and increase the performance of code using corelib methods (e.g. Fixnum methods)

Customization through build directives and API

To compensate for the described limitations, fastruby suport a few build directives to allow the programmer help the inference. The syntaxis of these directives are the same as normal ruby call (see examples) Also, fastruby will define a API to customize aspects of fastruby internals. E.g the build method to invoke the build of methods with a specific signature (see examples)

Installation

The install is as simple as execute the well-known gem install:

sudo gem install fastruby

Documentation

Overhead due new frame structure of reduce the speed to 20x (previously was near 100X). This refactor was necessary to implement most of the common ruby constructions (blocks, yields, breaks, next, exceptions, etc…) Since this first version of fastruby is in part an spike/PoC, there is no stable API to document. So, I recommend not to develop other software on top of fastruby since its API could change in any moment. But I will try as much as possible keep the backward compatibility in the near future

I will stabilize the API and document it for next releases. I promise

Known Limitations & Issues

  • fastruby now works with ruby1.9, but features specific to ruby1.9 (such fibers and new hash notation) will not work or will work with unexpected behaviour

  • fastruby on ruby1.8 is faster than ruby1.8 on a few cases (see benchmarks) but is slower than ruby1.9

  • callcc is not supported, it works but using it may result in unexpected behaviour

  • calls with blocks to ruby or cruby methods are almost as slow as normal ruby (if the called method is defined by fastruby, the call is pretty fast)

Usage

Environment variables

FASTRUBY_LOG define the output file of logging (default is standard output) FASTRUBY_LOG_LEVEL define the logging level (default 3) FASTRUBY_NO_CACHE set to 1 to disable the cache globally

Fastruby options

This options can be passed to fastruby when defining fastruby blocks

:no_cache set to true to disable cache (default: false) :validate_lvar_vars enable runtime check of assignments of typed variable (default: disabled)

Code Examples

The basic method is fastruby, fastruby takes a string with ruby code and compile it

Example 1: How invoke fastruby

require "fastruby"

class X
  fastruby '
  def foo
    print "hello world\n"
  end
  '
end

X.new.foo

Example 2: Prebuild

Normally, the method is built at runtime when is called with a new signature, You can prebuild the method to prevent this when the method is called for first time

require "fastruby"

class X
  fastruby '
  def foo(a,b)
    a+b
  end
  '
end

X.build([X,String,String] , :foo)

p X.new.foo("fast", "ruby") # will use the prebuilded method
p X.new.foo(["fast"], ["ruby"]) # will build foo for X,Array,Array signature and then execute it

Example 3: Explicit inference

Current fastruby allows to explictly define a type for a expression, a basic example show as tell to fastruby to assume that the result of to_s is of type String in the following case:

require "fastruby"

class X
  fastruby '
  def foo(a)
    a.to_s.infer(String) + "_"
  end
  '
end

p X.new.foo(9)

When fastruby can infer the type of an expression, the method calls that involve that expression can be accelerated. This is not necessary for arguments passed to a method or block

Example 4: Variable types

Like static languages, you can define a type for a variable to help the inference and gain some performance. This can be done by using lvar_type directive

class X
  fastruby '
  def foo
    lvar_type(i, Fixnum)
    i = 100
    while (i > 0)

i = i - 1

    end
    nil
  end
  '
end

With no lvar_type, the calls to Fixnum#> and Fixnum#- will be dynamic and more expensive

Copying

Copyright © 2011 Dario Seminara, released under the GPL License (see LICENSE)