« Return to Thread: Thoughts about RichObjects, Implicit convertions and performance

Re: Thoughts about RichObjects, Implicit convertions and performance

by David Hall-15 :: Rate this Message:

Reply to Author | View in Thread

On Mon, Mar 23, 2009 at 9:23 PM, Vladimir Kirichenko
<vladimir.kirichenko@...> wrote:

> One of the typical uses of implicit conversions is to declare
> "additional" methods for the existing class. Compiler substitutes
> reference to object with invocation of implicit function that typically
> instantiates some kind of RichObject or anonymous object with additional
> functions. For example
>
> var i = 5;
> i = i max 6;
> i = i max 7;
>
> will be compiled to 2 instantiations of RichInt. The use of anonymous
> declaration in implicit will cause big performance degradation.
>
> Also in these cases usually impossible to reuse created instance.
>
> The idea is to create some kind of "implicit traits" for this kind of
> situations that would not cause performance issues and also eliminates
> the need of implicit def declarations:
>
> implicit[Int] trait RichInt {
>        def max(x: Int) = this > x
>        def min(x: Int) = this < x
> }
>
> and the
>
> i = i max 6;
>
> will actually be compiled to "static" method invocation
>
> i = RichInt.max(i, 6);


A similar idea has been proposed along these lines before (albeit with
a different syntax), and I think it would be great to have something
like this. Someone--you? :-)--should spearhead a SIP for it.

First observation: I personally would prefer the syntax

implicit class RichInt(i: Int) {
  def max(o: Int) = if (i >= o) i else o
}

with the same semantics you propose, but that's mainly because I feel
icky about "this" pointing to something other than, well, "this".

Second observation, your benchmarking (below) is the "wrong" way to
benchmark JVM code because of the peculiarities of hotspot. You should
wrap these calls in a method and call it at least 10,000 times in a
method before clocking speeds. HotSpot can do amazing things when you
give it a chance.

That said, my understanding* is that HotSpot does not (yet**) do a
great job removing object creations, which is what is needed to really
make implicits faster.

-- David

* which could be wrong.
** see http://blog.juma.me.uk/2008/12/17/objects-with-no-allocation-overhead/

>
> The performance difference is significant
>
> object XT {
>
> implicit def int2x(i: Int) = new {
>    def sum(x: Int) = i + x
> }
>
> def sum(i:Int, x:Int) = i + x;
>
> def main(args : Array[String]) = {
>
>    //simple
>    val iterations = 10000000
>    var start = System.currentTimeMillis
>
>    var i=0;
>    var x=0;
>
>    while(i < iterations) {
>        x = x sum i sum i;
>        i = i + 1;
>    }
>
>    println(x + " in " + (System.currentTimeMillis - start) );
>
>    //fast
>    start = System.currentTimeMillis
>
>    i=0;
>    x=0;
>
>    while(i < iterations) {
>        x = sum(sum(x, i),i);
>        i = i + 1;
>    }
>
>    println(x + " in " + (System.currentTimeMillis - start) );
>
> }
> }
> =============
> 266447232 in 7557
> 266447232 in 20
>
>
>
> --
> Best Regards,
> Vladimir Kirichenko
>
>

 « Return to Thread: Thoughts about RichObjects, Implicit convertions and performance