If there is an implicit conversion from whatever types you need to convert to 
BigDecimal then this single overload should be sufficient:
public static BigDecimal/*!*/ Add(CodeContext/*!*/ context, BigDecimal/*!*/ 
self, BigDecimal/*!*/ b, int n)

The second overload you use now
public static BigDecimal/*!*/ Add(CodeContext/*!*/ context, BigDecimal/*!*/ 
self, object b, object n)

does conversions and call the first overload, right? In future the conversions 
will be described by attributes on the first overload and the second overload 
won't be necessary. It also depends how we define implicit conversions for 
BigDecimal. If an arbitrary method has a BigDecimal parameter should it be 
possible to pass Fixnum? If that is a common case (maybe with some exemptions) 
it might be reasonable to define an implicit conversion from Fixnum to 
BigDecimal. Then the single overload would handle all cases. Otherwise you 
would need overloads from all types of "b" parameter that this method can take.

Also, if you want to prevent allocation of BigDecimal for "b" parameter when 
Fixnum is passed in (which might be a good optimization) you need
public static BigDecimal/*!*/ Add(CodeContext/*!*/ context, BigDecimal/*!*/ 
self, int b, int n)

overload.

Note that the implicit conversions and protocol attributes are not supported 
right now. It will take some time to do so.
For now

public static BigDecimal/*!*/ Add(CodeContext/*!*/ context, BigDecimal/*!*/ 
self, BigDecimal/*!*/ b, int n)
public static BigDecimal/*!*/ Add(CodeContext/*!*/ context, BigDecimal/*!*/ 
self, object b, object n)

overloads with manual conversions might be good enough. If you want to optimize 
add overloads for int and double, unless the only thing they do is to allocate 
BigDecimal and call the first one. Then it doesn't make sense to optimize them.

Tomas

From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Peter Bacon 
Darwin
Sent: Saturday, July 19, 2008 1:26 PM
To: [email protected]
Subject: Re: [Ironruby-core] Multiple overloads VS Inline casting

So in the example I gave, what would be the preferred set of overloads?
Obviously from (1) there would be:
public static BigDecimal/*!*/ Add(CodeContext/*!*/ context, BigDecimal/*!*/ 
self, BigDecimal/*!*/ b, int n) ...
but what form should the "strongly typed overload" that you describe in (2) 
take?
Cheers,
Pete

From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Tomas Matousek
Sent: Saturday,19 July 19, 2008 20:50
To: [email protected]
Subject: Re: [Ironruby-core] Multiple overloads VS Inline casting

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.

Tomas

From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Peter Bacon 
Darwin
Sent: Saturday, July 19, 2008 12:03 PM
To: [email protected]
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) ...
and
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?

Pete
_______________________________________________
Ironruby-core mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core

Reply via email to