[Stk] Ruby extensions with STK

M. Edward (Ed) Borasky znmeb at cesmail.net
Wed, 05 Dec 2007 19:00:23 -0800


David Michael wrote:
> 
> Well I only have very preliminary results, but for a single sinusoid on 
> a Core 2 Duo (Mac) I was getting about 1.9% - 2.0% CPU usage from Ruby. 
> Comparatively, running crtsine.cpp natively compiled, I got 1.8% CPU 
> usage. This was with default buffer sizes. So the performance seems to 
> be pretty spot on. There is CPU overhead for running the Ruby 
> interpreter, but not that much. I am also curious on how fast it could 
> go: that is, how many instances I can manage, etc... In general I would 
> love to have this targeted to less-than-modern CPUs. I need to do much 
> more testing.
> 
> So the reason that interpreted languages are not good at realtime 
> synthesis seems to be that they are too slow to do the timely float 
> calculations of realtime audio (handling streams and whatnot) - but if 
> you offload the audio engine to C/C++ code, you should be able to get 
> decent performance and get to use a nice high level language like Ruby 
> to orchestrate objects.  Correct?
> 
> What would be really amazing would be a domain specific language for the 
> STK built off of Ruby for manipulating audio objects, but I have yet to 
> figure out how one would manage audio streams between Ruby objects...
> 
> Best
> David
> 
> -
> http://unnature.org


I have spent a fair amount of time profiling the Ruby interpreter -- see 
  http://rubyforge.org/docman/view.php/977/2705/Slides.pdf for the gory 
details. Briefly:

1. For most low-level benchmarks (things like fibonacci, ackerman, etc.) 
Ruby spends most of its time in the "inner interpreter" -- walking the 
syntax tree and dispatching method calls. And if you do a lot of object 
creation and then remove references to the objects, it spends a lot of 
time in the garbage collector.

2. There are three Ruby interpreters in common use and more in progress. 
The one most people are familiar with is the standard one that comes 
with most Linux distros, Ruby 1.8.6. Unless you compile this yourself 
from source, as you would with Gentoo, chances are you're getting 
something like 70 - 75 percent of the performance you could be getting 
with an optimal "gcc" compile.

The second Ruby interpreter is the one that will become Ruby 1.9 and is 
due out this Christmas. That one has an inner interpreter/virtual 
machine that's somewhere in the range of 3 - 6 times as fast as "stock" 
Ruby. And the third is jRuby, a Ruby interpreter and compiler built on 
the Java virtual machine by a couple of hard-core performance tuners at 
Sun. The last benchmarks I saw from the jRuby team showed them slightly 
faster than Ruby 1.9, and significantly faster on multi-precision 
integer operations.

There are three ways to optimize jRuby code:

a. Let the JIT compiler do it.
b. Compile Ruby with the Ahead-Of-Time compiler.
c. Build libraries in Java and interface to them.

In the case of Stk, since it's in C/C++, I don't think you'd be able to 
use jRuby, but you should be able to use Ruby 1.9. But for pure Ruby 
code, jRuby is worth looking at.

3. What would really be nice would be for someone to take the C/C++ Stk 
code and write SWIG interface files for it. What that gives you is 
access to *all* the scripting languages -- Ruby, Python, Perl, PHP, Lua, 
Pike, plus Java, a couple of Scheme and Lisp processors, and R.

4. The three Ruby interpreters differ in how they handle threads, if 
you're interested in using them. Ruby 1.8.6 uses so-called "green" 
threads. The interpreter has its own scheduler and dispatcher, so on a 
multi-core box, you only use one core per instance of the Ruby 
interpreter. jRuby uses the threading mechanisms in the Java Virtual 
Machine, which in turn use native platform threading mechanisms. And 
Ruby 1.9 uses native platform threading directly.