[Ironruby-core] Multiple overloads VS Inline casting
Tomas.Matousek at microsoft.com
Sat Jul 19 15:49:57 EDT 2008
We are well aware of this issue and have a plan to solve it:
1) You define overloads for type combinations that you want to optimize. I'm going to improve class initializers to have a less overhead. Even now though the initialization doesn't contribute significantly to startup time.
2) For the rest of the parameter type combinations whose performance is not critical you define a strongly typed overload(s) that can accept all of them. The conversions should happen automatically in the binder. There will be some well defined conversions + a set of attributes to customize them. The goal is not to perform type conversions imperatively in library code if possible. The predefined conversions will follow Ruby conversion protocols like to_i, to_s, etc. If a particular method doesn't support the default conversion (Ruby library methods are inconsistent on what conversions are used) or a there are multiple applicable conversions to chose from, attributes would be available to specify the right one.
From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Peter Bacon Darwin
Sent: Saturday, July 19, 2008 12:03 PM
To: ironruby-core at rubyforge.org
Subject: [Ironruby-core] Multiple overloads VS Inline casting
I have noticed in the libraries that are often methods that take multiple parameters and each parameter can take a number of different types. A simple example, BigDecimal#add method has two parameters: a.add(b,n), where a is BigDecimal, b needs to be compatible with BigDecimal and n needs to be compatible with Fixnum. In other words it is possible that b and n can be one of [NotNull]BigDecimal/*!*/, [NotNull]BigInteger/*!*/, int, double and object. This leads to an implementation question.
Initially it seemed sensible to abstract out the conversion of these types - except perhaps the best case ([NotNull]BigDecimal/*!*/ and int) - into a helper method and then have just:
public static BigDecimal/*!*/ Add(CodeContext/*!*/ context, BigDecimal/*!*/ self, BigDecimal/*!*/ b, int n) ...
public static BigDecimal/*!*/ Add(CodeContext/*!*/ context, BigDecimal/*!*/ self, object b, object n) ...
In the second method you convert the parameters to the correct types and pass them back to the first method. This is basically what happens in the current implementation of many of the Socket library methods. This provides a single place of conversion, which is particularly helpful given the BigDecimal class has lots of methods that take this form that will all use this conversion. It makes the code readable and doesn't create masses of overloads for the class.
After thinking about this for a bit I started to wonder about performance. This style of method does not allow performance tricks in the DLR to benefit the code. If you have the type lookup inside the methods then that gets called every single time those methods are called.
The other implementation idea then is to create method overloads for all the permutations of the parameter types. This leads to a massive increase in methods but could provide better performance at run time; It may happen already, or it certainly could in the future, that the DLR is able to calculate the method required from the calling code (i.e. Ruby code) and generate IL that will call that method directly during execution. Therefore the type lookup only needs to happen once. This would make a huge difference in some of the BigDecimal functionality where you may well be doing complex calculations and expecting a reasonable level of performance. The trouble with this is that it is a right pain to code up and leaves lots of room for programmer error. Also I imagine that this will lead to even longer start-up times for IronRuby, which I suspect is going to be the major performance issue going forward, what with all the code generation and JIT compilation.
Any one got thoughts on this?
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Ironruby-core