On Tue, Oct 27, 2009 at 9:39 PM, Bill K. [email protected] wrote:
(Or maybe such a thing would instead be achieved at
run-time through JIT’ing and sophisticated hotspot
analysis?)
Anything is possible. It’s just really hard.
Even the best optimized dynamic language runtimes, many of which can
put values into registers and turn math into extremely fast low-level
native operations, still need to obey the semantics of the language.
In Ruby’s case, that means you still need to ensure that the values
being passed into a numeric algorithm are actually Fixnums and make
sure that Fixnum itself has not been modified. If you don’t check the
former, you may do optimized math against a non-math value. If you
don’t do the former, Fixnum’s mutability could lead to method
replacements (uncommon for math, admittedly) not being reflected in
already-optimized code. Performing those checks might be cheap, but
it’s never free. In Duby, as in the JVM below it, if you’re working
with a primitive int, you’ll always be working with a primitive int.
Similar (but perhaps not as strong) guarantees apply to non-primitive
types.
behavior in a real system where the arithmetic operations
‘fair’ to Smalltalk?
I’m going to have to call shenanigans on that.
Shenanigans indeed! I’ve made the same sorts of claims myself, like
“JRuby is only a couple times slower than Java, /for equivalent
work/”. That’s my subtle way of saying “Java numeric algorithms that
work with all boxed 64-bit values and do virtual dispatches for all
math operations.” It evens the playing field, but of course nobody
writing Java would write numeric algorithms performing virtual calls
against boxed 64-bit values. In my defense, however, math is one of
the few areas where JRuby will probably never be as fast as Java (or
Ruby implementations that don’t need to use objects for Fixnums),
since our dynamic calls are almost as fast now as Java’s virtual or
interface calls. If you’re working with a bunch of non-numeric objects
in JRuby, we do very well.
But anyway, if it’s truly theoretically possible to achieve C-like speeds in
ruby without giving any hints to
the compiler then I’m all for it (obviously).
It’s certainly possible to do much better than we have been doing.
MacRuby and Rubinius, for example, are now showing extremely good perf
numbers for numeric algorithms. In Rubinius’s case, the recent JIT
work has started to make it conceivable that a pure-Ruby standard
library may be able to get within a few times of MRI’s
implementations. And experiments with JRuby have been able to double
or triple our current Ruby performance, simply by making it easier for
the JVM to optimize Ruby code the same way it optimizes Java code. We
are able to approach both MacRuby and Rubinius even for numeric
algorithms where they have an advantage. It’s an uphill battle–the
nature of Ruby is such that even our best efforts are littered with
performance-stealing typechecks–but we’re all making great progress
and learning from each others’ efforts.
Even if Ruby could run as fast as C (or Java, in my case) it would
still not fit the other requirements of Duby, like having no runtime
library or being able to present “real” Java classes and methods. So I
think even under the best circumstances, Duby (or something like it)
is still needed.
Otherwise, the remarkably unobtrusive type hinting Charlie
is experimenting with seems to me vastly preferable to
the current situation of having to drop into C to get the
speed. Â I don’t like static typing. Â But I like having
to drop from Ruby into C even less.
Just as I find it ironic that I work all day, every day, implementing
Ruby…by writing in Java. It has led to a very solid, reasonably
performant implementation, but it would be a lot more fun to write in
something Ruby-like. If I can get much of what I like about Ruby by
using Duby and pay no performance penalty at all, I’d be very happy.
And you all might find it easier to contribute to JRuby, too 
in effect provide an optional fast-path for users who were
in need of maximum speed, without imposing any un-ruby-like
restrictions on other users?
If that were possible, would there be any downside? Â (An
honest question. Â I’m not thinking of any myself, so far.)
Interesting that you suggest this. I am also going to add dynamic
dispatch to Duby.
A second language project of mine, Surinx, is essentially Ruby syntax,
Java/JVM types, but all dynamic calls. It requires the dynamic
dispatch support coming up in Java 7, and it has a small runtime
library, but otherwise it is also written entirely in Ruby.
Performance is rather interesting with Surinx; it’s much faster than
JRuby, since it doesn’t have to deal with a mutable type system and it
lets the JVM optimized dynamic calls. For “equivalent work”, Surinx is
only about 50% slower than Java, and that gap is likely to narrow as
the Hotspot engineers improve dynamic call optimzations.
But there’s no real reason to keep the languages separate, so I intend
to merge them. The new language will be statically typed, except where
types cannot be statically determined (or perhaps where you explicitly
declare them as dynamic). If you write with no static types at all,
there will be very little to distinguish the syntax from plain old
Ruby (though of course it’s still not Ruby, because it’s still based
on Java’s type system and class libraries).
Dean W. suggested the name “Dubious”, which seems to fit its
dubious nature extremely well.
Surinx and Duby codebases are on my github account.