Wednesday, June 4, 2008

Dynamic Language Optimizations: Polymorphic Inline Caches

The biggest performance problem with dynamic languages is that almost everything reduces to a lookup of a method call:

x = a + b
This actually works out to:
  • send the '+' message to the object referenced by 'a' with an argument of 'b'.
  • if the class of object 'a' doesn't respond to '+', consult the parent class of 'a'.
  • if the parent class doesn't respond to '+' continue up the class hierarchy until you find a class that does.
  • if no ancestor class responds to '+' see if the object referenced implements 'method_missing'.
  • if not do the same search up the ancestor tree for this method.
  • once you have found an implementation of '+' or 'method_missing', call it with the argument 'b'.
  • take the result of this method call and use it as an argument and send the '=' message to 'x' .
  • Rinse and repeat.
So the first optimization at a given call site is to cache the result of the last lookup. So next time through if 'a' is the same class as before, we already know the method pointer, assuming a long laundry list of items ('a' hasn't implemented an instance method of the same name, no one has modified the definition of this method in the parent classes, etc).

The next optimization is polymorphic inline caches. Of course, every paper by the Self guys should be studied. 


No comments: