Ruby and C. Part 1.
Ruby integrates very easily with the C programming language. You can create extensions for Ruby. Or we can do a wrapper for a C library, and use it like a regular Ruby library. You can also implement critical computing in C directly in Ruby code! Another integration option is to use Ruby in C / C ++ programs as a scripting language. For example, how it is done in Google SketchUp.
Let's see what features Ruby presents for integration with C.
Let there be a bottleneck in our program, some piece of computation that, for example, runs in a loop. These calculations greatly reduce the performance of the application.
The solution is to rewrite the critical piece to C, because compiled languages are obviously faster than interpreted ones.
Here we have two options: either create an extension for Ruby, or use the C code directly from Ruby.
To begin with, we will choose the second option, and the RubyInline library will come to our aid in this.
Suppose we have a method for decomposing a number into prime divisors. Let's go along the simplest way, and implement this method with an iterative algorithm:
But we are not happy with the speed of this method, so we will rewrite it in C using the RubyInline library.
First, install it:
RubyInline requires a POSIX system, i.e., either * nix or Cygwin on Windows.
As well as the C / C ++ compiler.
A simple use case:
In the sample code, we made a small C method that returns a hello string.
The method
- performs conversion of argument types and return value from C to Ruby
- compiles a string with the method code
- adds the test method to the Test class.
After that, we can use it
Let's get back to factorization. Rewrite the factorization method with RubyInline.
And now, the most interesting. Performance tests.
Ruby test implementation:
Result:
And similar to C:
And the result:
As you can see from the test, RubyInline allows you to accelerate critical pieces of code by almost 10 times!
Test code: factor.rb , factorfast.rb .
Summing up, we can say that if our application does not cope with the load, then we can always speed it up by implementing critical points in C. Fortunately, Ruby provides us with powerful and convenient tools for this.
In the next part I will talk about creating C extensions for Ruby.
Related links:
RubyInline: http://rubyforge.org/projects/rubyinline/
Documentation: http://rubyinline.rubyforge.org/RubyInline/
Let's see what features Ruby presents for integration with C.
Let there be a bottleneck in our program, some piece of computation that, for example, runs in a loop. These calculations greatly reduce the performance of the application.
The solution is to rewrite the critical piece to C, because compiled languages are obviously faster than interpreted ones.
Here we have two options: either create an extension for Ruby, or use the C code directly from Ruby.
To begin with, we will choose the second option, and the RubyInline library will come to our aid in this.
Suppose we have a method for decomposing a number into prime divisors. Let's go along the simplest way, and implement this method with an iterative algorithm:
class factor #num - input number, show - whether to display the result on the screen def factorization num, show = false num1 = num n = 2 # start the search for divisors from two while n * n <= num1 if num% n == 0 # if the current number is a divisor, print it num = num / n puts n if show else # otherwise increase the current number n + = 1 end end end end
But we are not happy with the speed of this method, so we will rewrite it in C using the RubyInline library.
First, install it:
gem install RubyInline
RubyInline requires a POSIX system, i.e., either * nix or Cygwin on Windows.
As well as the C / C ++ compiler.
A simple use case:
require 'rubygems' require 'inline' # connect RubyInline class test # embedded code handler inline do | builder | # an Inline :: C class object is passed to the block builder.c ' static char * test () { return "Hi from C! :)"; } '' end end puts Test.new.test # prints "Hi from C! :)"
In the sample code, we made a small C method that returns a hello string.
The method
c
performs the following actions: - performs conversion of argument types and return value from C to Ruby
- compiles a string with the method code
- adds the test method to the Test class.
After that, we can use it
test
as a regular Ruby method. Let's get back to factorization. Rewrite the factorization method with RubyInline.
require 'rubygems' require 'inline' class FastFactor inline do | builder | builder.c ' static void factorization (int num, int show) { int i = 0; int num1 = num; int n = 2; while (n * n <= num1) { if (num% n == 0) { num = num / n; if (show) printf ("% d \ n", n); i ++; } else { n ++; } } } '' end end
And now, the most interesting. Performance tests.
Ruby test implementation:
f = Factor.new 1000.times {f.factorization 999999}
Result:
$ time ruby factor.rb real 0m1.034s user 0m1.028s sys 0m0.004s
And similar to C:
f = FastFactor.new 1000.times {f.factorization 999999, false}
And the result:
time ruby factorfast.rb real 0m0.116s user 0m0.092s sys 0m0.024s
As you can see from the test, RubyInline allows you to accelerate critical pieces of code by almost 10 times!
Test code: factor.rb , factorfast.rb .
Summing up, we can say that if our application does not cope with the load, then we can always speed it up by implementing critical points in C. Fortunately, Ruby provides us with powerful and convenient tools for this.
In the next part I will talk about creating C extensions for Ruby.
Related links:
RubyInline: http://rubyforge.org/projects/rubyinline/
Documentation: http://rubyinline.rubyforge.org/RubyInline/