Saturday, December 26, 2009

The Guilt of not writing here more....

I am being kept honest enough to do a monthly blog on Engine Yard's site. Here is a link from one I did at the end of November (belated linkage):

http://www.engineyard.com/blog/2009/j-is-for-jvm-why-the-j-in-jruby/

My new years resolution is to write here at least a little :)

Happy New Year!

Friday, September 11, 2009

JRubyConf to follow RubyConf

A JRuby-specific event has been a mythical beast for some time now. Only skirting reality in emails and in the back of not-too-seedy bars...UNTIL now. That's right...JRubyConf! We are having a one day event to cover all things JRuby the day after RubyConf (Sunday, November 22. 2009) in the same hotel as RubyConf itself. Talks will cover Rails (Traditional + GAE), Monkeybars, and more (website will have details). Admission is free but there are a limited number of seats, so sign up soon.

Monday, July 20, 2009

Fun in Japan: set meals

This month I am spending time in Tokyo to speak at RubyKaigi. I also will be
visiting Fukuoka briefly for another conference. It is great being in Japan.
One great aspect of visiting Japan is trying the large variety of food here.
Besides really common (read that as US common) types like Soba, Ramen, Sushi,
Tempura, Shabu-Shabu or Yakitori you can also have other common foodstuffs
in Japan like Okinomiyaki, Chankonabe, and many others. In fact, each time
I visit I am introduced to new styles of food (Chankonabe and Oyakudon so far
this trip).

If you are adventurous you can try exotic dishes like Fugu (Pufferfish), to
somewhat stranger dishes like Horse Shashimi (bland). Or if you are very
strange you can have Gotemono (Japanese virility food!). But this entry is
about a meta-aspect of eating in Japan: set meals.

In the US, we have some restaurants that have multiple courses, but in Japan it
seems much more common. All restaurants here which specialize in a single
type of food seems to have a set meal. For example, ff you have had
Unagi/Anago at a US restaurant it is generally just an entree. If you have
an Unagi set meal you get something like the following:


1. Eel spines (salty and crunchy)


2. Eel fins and livers on a stick! (fins are decent -- livers not as decent)


3. Eel omelet



4. Eel fillet


5. Eel salad (with fresh water eel)


6. Eel rice bowl with miso soup

Cool huh?

The biggest problems with ordering set meals is understanding the menu.
Frequently these menus are written in Kanji and generally in an artistic form
of Kanji, which can render even easy to read Kanji unintelligible (well to me
anyways). If you are with a Japanese companion this obviously works best
because they can: read the menu, tell you how to eat each dish, also give
nice facts about the food (e.g. "Those are guts"), and just generally be fun
to hang out with.

If you cannot find someone to take you to a restaurant, then just try one and
be adventurous. Quite a large number of people can speak English in Japan.
They can be shy about using English, but odds are you can find a restaurant
where between a little common ground with English and a Japanese-English
dictionary you can probably get in on the set meal action.

Wednesday, July 8, 2009

Block Assignment Refactoring Fun...

I have been refactoring some of our block dispatch code recently. These changes are currently only for the interpreter, but they can easily be adapted for the compiler later. In fact, I think I can adapt this for our interpreters method parameter assignment and also unify it with our Ruby 1.9 assignment code (for both blocks and methods). But I am getting a head of myself. Why refactor block assignment code?

Block assignment code is one of the ickiest pieces of logic in JRuby and for that matter in Ruby. Lots and lots of conditional logic to pad things out and even weirder logic when your block has one parameter and it is a RubyArray (perhaps not as weird as when it isn't a RubyArray). So there were three goals in the refactoring:
  1. Make each type of block parameter signature it's own code path with little or no conditional logic
  2. Try and make the logic for the strange cases more readable
  3. Try and speed up block invocation

The refactoring is to have InterpretedBlock (and by extension SharedBlock) contain a new attribute called assigner of base type Assigner. A new class Assigner has split-arity call paths and a boxed catch-all assign method. Also, a special RubyArray version assignArray for the most ugly block assignment case:

public abstract class Assigner {
public abstract void assign(Ruby runtime, ThreadContext context, IRubyObject self, Block block);
public abstract void assign(Ruby runtime, ThreadContext context, IRubyObject self, IRubyObject value1, Block block);
public abstract void assign(Ruby runtime, ThreadContext context, IRubyObject self, IRubyObject value1, IRubyObject value2, Block block);
public abstract void assign(Ruby runtime, ThreadContext context, IRubyObject self, IRubyObject value1, IRubyObject value2, IRubyObject value3, Block block);
public abstract void assign(Ruby runtime, ThreadContext context, IRubyObject self, IRubyObject[] values, Block block);
public abstract void assignArray(Ruby runtime, ThreadContext context, IRubyObject self, IRubyObject values, Block block);
// ...
}
For each type of block parameter signature we have a subclass of Assigner which implements these assign methods with the proper minimalist code to do assignment in that case. So for a block which has a single required argument and a rest argument (Pre1Rest1Assigner) we have an unboxed 2 argument assign method which looks like:

public void assign(Ruby runtime, ThreadContext context, IRubyObject self, IRubyObject value1,
IRubyObject value2, Block block) {
parameter1.assign(runtime, context, self, value1, block, false);

rest.assign(runtime, context, self, runtime.newArrayNoCopyLight(value2), block, true);
}
All in all I think the code reads much nicer than it did. There are still some uses of the old code which need to be eliminated in a future refactoring, but I think the code is in better shape than it was.

This along with creating split-arity versions of YieldNode ended up yielding some good results (both running jruby -X-C --server bench/language/bench_yield.rb):

Before After Improvement
1m x10 yield 1 to { } 1.304000 1.139000 ~12%
1m x10 yield to { } 1.253000 1.174000 ~6%
1m x10 yield 1 to {|j| j} 1.572000 1.474000 ~0.6%
1m x10 yield 1,2 to {|j,k| k} 2.228000 1.570000 ~30%
1m x10 yield 1,2,3 to {|j,k,l| k} 2.607000 1.731000 ~33%
1m x10 yield to {|j,k,l| k} 2.921000 1.710000 ~41%
1m x10 yield 1,2,3 to {|*j| j} 3.009000 2.492000 ~17%
1m x10 yield to {1} 1.313000 1.273000 ~0.3%

It is always good when things get faster after a refactoring.... :)