This page is no longer maintained — Please continue to the home page at www.scala-lang.org

How to avoid Int and Double boxing in a returned tuple ?

14 replies
guast
Joined: 2010-12-31,
User offline. Last seen 1 year 36 weeks ago.

Hi All

I have a method that returns a tuple of (Int, Double, Double). I am
returning some fields of the same type. However in the generated class
I can see that the value are boxed. That method will be called
millions of times so I am trying to optimize it as much as possible,
but I can't avoid the boxing. Is there a way to do it ?

This is the last version of the method:

private def getIterations(x:Double, y:Double, x_0:Double,
y_0:Double, iterations: Int):(Int, Double,
Double) = {
if (iterations < maxIterations && x*x + y*y <= 4)
getIterations(x*x - y*y + x_0, x*y*2.0 + y_0, x_0, y_0,
iterations+1)
else (iterations, x, y)
}

This is the generated code:
final def mandelbrotsetdesigner$FunctionIterator$$getIterations(x:
Double, y: Double, x_0: Double, y_0: Double, iterations: Int): Tuple3
= {
val _$this: mandelbrotsetdesigner.FunctionIterator =
FunctionIterator.this;
_getIterations(_$this,x,y,x_0,y_0,iterations){
if (iterations.<(FunctionIterator.this.maxIterations()).&&(x.*(x).+
(y.*(y)).<=(4)))
_getIterations(FunctionIterator.this, x.*(x).-(y.*(y)).+(x_0),
x.*(y).*(2.0).+(y_0), x_0, y_0, iterations.+(1))
else
new Tuple3(scala.Int.box(iterations), scala.Double.box(x),
scala.Double.box(y))
}
};

----------------------------------------------------
I tried this way as well, but it didn't work

case class SpecializedTupleT3 [@specialized(Int) TT1,
@specialized(Double)
TT2,
@specialized(Double)
TT3](_1:TT1, _2:TT2, _3:TT3)
private def getIterations(x:Double, y:Double, x_0:Double,
y_0:Double, iterations: Int):SpecializedTupleT3[Int, Double,
Double] = {
if (iterations < maxIterations && x*x + y*y <= 4)
getIterations(x*x - y*y + x_0, x*y*2.0 + y_0, x_0, y_0, iterations
+1)
else new SpecializedTupleT3[Int, Double, Double](iterations, x, y)
}

-------------

Thanks

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: How to avoid Int and Double boxing in a returned tuple ?
The specialized version should work (you were probably not looking at the SpecializedTuple3$mcIDD$sp class which is the specialized version that is generated and will be used if all the parameters match), but it's overkill for your application.  Just use a case class--and then you can name your variables something sensible also!

  case class MbIter(i: Int, x: Double, y: Double) {}
  ...
    else MbIter(iterations, x, y)  
  ...

  --Rex

On Sat, Dec 31, 2011 at 6:16 AM, guast <v [dot] guast [at] gmail [dot] com> wrote:
Hi All

I have a method that returns a tuple of (Int, Double, Double). I am
returning some fields of the same type. However in the generated class
I can see that the value are boxed. That method will be called
millions of times so I am trying to optimize it as much as possible,
but I can't avoid the boxing. Is there a way to do it ?

This is the last version of the method:

private def getIterations(x:Double, y:Double, x_0:Double,
                         y_0:Double, iterations: Int):(Int, Double,
Double) = {
 if (iterations < maxIterations && x*x + y*y <= 4)
     getIterations(x*x - y*y + x_0, x*y*2.0 + y_0, x_0, y_0,
iterations+1)
 else (iterations, x, y)
}

This is the generated code:
final def mandelbrotsetdesigner$FunctionIterator$$getIterations(x:
Double, y: Double, x_0: Double, y_0: Double, iterations: Int): Tuple3
= {
 <synthetic> val _$this: mandelbrotsetdesigner.FunctionIterator =
FunctionIterator.this;
 _getIterations(_$this,x,y,x_0,y_0,iterations){
   if (iterations.<(FunctionIterator.this.maxIterations()).&&(x.*(x).+
(y.*(y)).<=(4)))
     _getIterations(FunctionIterator.this, x.*(x).-(y.*(y)).+(x_0),
x.*(y).*(2.0).+(y_0), x_0, y_0, iterations.+(1))
   else
     new Tuple3(scala.Int.box(iterations), scala.Double.box(x),
scala.Double.box(y))
 }
};

----------------------------------------------------
I tried this way as well, but it didn't work

case class SpecializedTupleT3 [@specialized(Int) TT1,
                                              @specialized(Double)
TT2,
                                              @specialized(Double)
TT3](_1:TT1, _2:TT2, _3:TT3)
private def getIterations(x:Double, y:Double, x_0:Double,
                         y_0:Double, iterations: Int):SpecializedTupleT3[Int, Double,
Double] = {
 if (iterations < maxIterations && x*x + y*y <= 4)
   getIterations(x*x - y*y + x_0, x*y*2.0 + y_0, x_0, y_0, iterations
+1)
 else new SpecializedTupleT3[Int, Double, Double](iterations, x, y)
}

-------------

Thanks

guast
Joined: 2010-12-31,
User offline. Last seen 1 year 36 weeks ago.
Re: How to avoid Int and Double boxing in a returned tuple ?

Thanks for the answer.

I tried again, but eventually to avoid the forced boxing I created my
own box and it was even slower.

On Dec 31, 1:16 pm, Rex Kerr wrote:
> The specialized version should work (you were probably not looking at the
> SpecializedTuple3$mcIDD$sp class which is the specialized version that is
> generated and will be used if all the parameters match), but it's overkill
> for your application.  Just use a case class--and then you can name your
> variables something sensible also!
>
>   case class MbIter(i: Int, x: Double, y: Double) {}
>   ...
>     else MbIter(iterations, x, y)
>   ...
>
>   --Rex
>
>
>
>
>
>
>
> On Sat, Dec 31, 2011 at 6:16 AM, guast wrote:
> > Hi All
>
> > I have a method that returns a tuple of (Int, Double, Double). I am
> > returning some fields of the same type. However in the generated class
> > I can see that the value are boxed. That method will be called
> > millions of times so I am trying to optimize it as much as possible,
> > but I can't avoid the boxing. Is there a way to do it ?
>
> > This is the last version of the method:
>
> > private def getIterations(x:Double, y:Double, x_0:Double,
> >                          y_0:Double, iterations: Int):(Int, Double,
> > Double) = {
> >  if (iterations < maxIterations && x*x + y*y <= 4)
> >      getIterations(x*x - y*y + x_0, x*y*2.0 + y_0, x_0, y_0,
> > iterations+1)
> >  else (iterations, x, y)
> > }
>
> > This is the generated code:
> > final def mandelbrotsetdesigner$FunctionIterator$$getIterations(x:
> > Double, y: Double, x_0: Double, y_0: Double, iterations: Int): Tuple3
> > = {
> >   val _$this: mandelbrotsetdesigner.FunctionIterator =
> > FunctionIterator.this;
> >  _getIterations(_$this,x,y,x_0,y_0,iterations){
> >    if (iterations.<(FunctionIterator.this.maxIterations()).&&(x.*(x).+
> > (y.*(y)).<=(4)))
> >      _getIterations(FunctionIterator.this, x.*(x).-(y.*(y)).+(x_0),
> > x.*(y).*(2.0).+(y_0), x_0, y_0, iterations.+(1))
> >    else
> >      new Tuple3(scala.Int.box(iterations), scala.Double.box(x),
> > scala.Double.box(y))
> >  }
> > };
>
> > ----------------------------------------------------
> > I tried this way as well, but it didn't work
>
> > case class SpecializedTupleT3 [@specialized(Int) TT1,
> >                                               @specialized(Double)
> > TT2,
> >                                               @specialized(Double)
> > TT3](_1:TT1, _2:TT2, _3:TT3)
> > private def getIterations(x:Double, y:Double, x_0:Double,
> >                          y_0:Double, iterations:
> > Int):SpecializedTupleT3[Int, Double,
> > Double] = {
> >  if (iterations < maxIterations && x*x + y*y <= 4)
> >    getIterations(x*x - y*y + x_0, x*y*2.0 + y_0, x_0, y_0, iterations
> > +1)
> >  else new SpecializedTupleT3[Int, Double, Double](iterations, x, y)
> > }
>
> > -------------
>
> > Thanks

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: Re: How to avoid Int and Double boxing in a returned tuple
You're benchmarking wrong if you find that case classes are _slower_ than tuples.  (Unless there is some other source of boxing/unboxing and you're actually making it worse by storing primitives in case classes.)

  --Rex

On Sat, Dec 31, 2011 at 8:38 AM, guast <v [dot] guast [at] gmail [dot] com> wrote:
Thanks for the answer.

I tried again, but eventually to avoid the forced boxing I created my
own box and it was even slower.

On Dec 31, 1:16 pm, Rex Kerr <icho [dot] [dot] [dot] [at] gmail [dot] com> wrote:
> The specialized version should work (you were probably not looking at the
> SpecializedTuple3$mcIDD$sp class which is the specialized version that is
> generated and will be used if all the parameters match), but it's overkill
> for your application.  Just use a case class--and then you can name your
> variables something sensible also!
>
>   case class MbIter(i: Int, x: Double, y: Double) {}
>   ...
>     else MbIter(iterations, x, y)
>   ...
>
>   --Rex
>
>
>
>
>
>
>
> On Sat, Dec 31, 2011 at 6:16 AM, guast <v [dot] gu [dot] [dot] [dot] [at] gmail [dot] com> wrote:
> > Hi All
>
> > I have a method that returns a tuple of (Int, Double, Double). I am
> > returning some fields of the same type. However in the generated class
> > I can see that the value are boxed. That method will be called
> > millions of times so I am trying to optimize it as much as possible,
> > but I can't avoid the boxing. Is there a way to do it ?
>
> > This is the last version of the method:
>
> > private def getIterations(x:Double, y:Double, x_0:Double,
> >                          y_0:Double, iterations: Int):(Int, Double,
> > Double) = {
> >  if (iterations < maxIterations && x*x + y*y <= 4)
> >      getIterations(x*x - y*y + x_0, x*y*2.0 + y_0, x_0, y_0,
> > iterations+1)
> >  else (iterations, x, y)
> > }
>
> > This is the generated code:
> > final def mandelbrotsetdesigner$FunctionIterator$$getIterations(x:
> > Double, y: Double, x_0: Double, y_0: Double, iterations: Int): Tuple3
> > = {
> >  <synthetic> val _$this: mandelbrotsetdesigner.FunctionIterator =
> > FunctionIterator.this;
> >  _getIterations(_$this,x,y,x_0,y_0,iterations){
> >    if (iterations.<(FunctionIterator.this.maxIterations()).&&(x.*(x).+
> > (y.*(y)).<=(4)))
> >      _getIterations(FunctionIterator.this, x.*(x).-(y.*(y)).+(x_0),
> > x.*(y).*(2.0).+(y_0), x_0, y_0, iterations.+(1))
> >    else
> >      new Tuple3(scala.Int.box(iterations), scala.Double.box(x),
> > scala.Double.box(y))
> >  }
> > };
>
> > ----------------------------------------------------
> > I tried this way as well, but it didn't work
>
> > case class SpecializedTupleT3 [@specialized(Int) TT1,
> >                                               @specialized(Double)
> > TT2,
> >                                               @specialized(Double)
> > TT3](_1:TT1, _2:TT2, _3:TT3)
> > private def getIterations(x:Double, y:Double, x_0:Double,
> >                          y_0:Double, iterations:
> > Int):SpecializedTupleT3[Int, Double,
> > Double] = {
> >  if (iterations < maxIterations && x*x + y*y <= 4)
> >    getIterations(x*x - y*y + x_0, x*y*2.0 + y_0, x_0, y_0, iterations
> > +1)
> >  else new SpecializedTupleT3[Int, Double, Double](iterations, x, y)
> > }
>
> > -------------
>
> > Thanks

guast
Joined: 2010-12-31,
User offline. Last seen 1 year 36 weeks ago.
Re: How to avoid Int and Double boxing in a returned tuple ?

It's the second option. I tried to wrap everything in the case class
leaving outside just the bare recursive call. Too bad.
Actually I gave up and I tried the dirty fix. Instead of returning a
tuple the methods returns unit and sets the return values in some
class parameters.
I couldn't benchmark just that part of code, but I see that the whole
application is a about 10% faster.

I think it happens because the tuples of three of more parameters are
not specialized, probably it's too heavy.
I'll go back on that part of code when I'll learn better how
@specialized work.

Thanks

On Jan 1, 7:06 am, Rex Kerr wrote:
> You're benchmarking wrong if you find that case classes are _slower_ than
> tuples.  (Unless there is some other source of boxing/unboxing and you're
> actually making it worse by storing primitives in case classes.)
>
>   --Rex

Simon Ochsenreither
Joined: 2011-07-17,
User offline. Last seen 42 years 45 weeks ago.
Re: How to avoid Int and Double boxing in a returned tuple ?
Hi,

“it didn't work” -> Compile error? Runtime error? VM crash? Slow performance?

Hint: Most people can't read minds.

I'm pretty sure nobody can help you with that description.  :-)

Bye
sreque 2
Joined: 2011-11-15,
User offline. Last seen 42 years 45 weeks ago.
Re: How to avoid Int and Double boxing in a returned tuple ?

Even if there is no boxing happening, returning three values can be
slower than setting them on an existing object because the return
object still has to be allocated on the heap. Even in C++, for
efficiency's sake large structs aren't returned, either on the stack
or on the heap. Rather, the caller passes in a struct by reference
that the callee modifies, so that it is the caller's responsibility to
deal with the memory allocation.

On Jan 1, 11:58 am, guast wrote:
> It's the second option. I tried to wrap everything in the case class
> leaving outside just the bare recursive call. Too bad.
> Actually I gave up and I tried the dirty fix. Instead of returning a
> tuple the methods returns unit and sets the return values in some
> class parameters.
> I couldn't benchmark just that part of code, but I see that the whole
> application is a about 10% faster.
>
> I think it happens because the tuples of three of more parameters are
> not specialized, probably it's too heavy.
> I'll go back on that part of code when I'll learn better how
> @specialized work.
>
> Thanks
>
> On Jan 1, 7:06 am, Rex Kerr wrote:
>
>
>
>
>
>
>
> > You're benchmarking wrong if you find that case classes are _slower_ than
> > tuples.  (Unless there is some other source of boxing/unboxing and you're
> > actually making it worse by storing primitives in case classes.)
>
> >   --Rex

Ahaly Kumar
Joined: 2011-10-03,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: How to avoid Int and Double boxing in a returned tuple

How do we prevent auto-boxing when we used case classes? The case class instance would still be initiated with a Int or a Double - right? Also does this mean it is not recommended to use Int, Double etc in Tuples?
- Ahaly "newbie" Kumar

On Dec 31, 2011, at 10:06 PM, Rex Kerr wrote:
You're benchmarking wrong if you find that case classes are _slower_ than tuples.  (Unless there is some other source of boxing/unboxing and you're actually making it worse by storing primitives in case classes.)

  --Rex

On Sat, Dec 31, 2011 at 8:38 AM, guast <v [dot] guast [at] gmail [dot] com> wrote:
Thanks for the answer.

I tried again, but eventually to avoid the forced boxing I created my
own box and it was even slower.

On Dec 31, 1:16 pm, Rex Kerr <icho [dot] [dot] [dot] [at] gmail [dot] com> wrote:
> The specialized version should work (you were probably not looking at the
> SpecializedTuple3$mcIDD$sp class which is the specialized version that is
> generated and will be used if all the parameters match), but it's overkill
> for your application.  Just use a case class--and then you can name your
> variables something sensible also!
>
>   case class MbIter(i: Int, x: Double, y: Double) {}
>   ...
>     else MbIter(iterations, x, y)
>   ...
>
>   --Rex
>
>
>
>
>
>
>
> On Sat, Dec 31, 2011 at 6:16 AM, guast <v [dot] gu [dot] [dot] [dot] [at] gmail [dot] com> wrote:
> > Hi All
>
> > I have a method that returns a tuple of (Int, Double, Double). I am
> > returning some fields of the same type. However in the generated class
> > I can see that the value are boxed. That method will be called
> > millions of times so I am trying to optimize it as much as possible,
> > but I can't avoid the boxing. Is there a way to do it ?
>
> > This is the last version of the method:
>
> > private def getIterations(x:Double, y:Double, x_0:Double,
> >                          y_0:Double, iterations: Int):(Int, Double,
> > Double) = {
> >  if (iterations < maxIterations && x*x + y*y <= 4)
> >      getIterations(x*x - y*y + x_0, x*y*2.0 + y_0, x_0, y_0,
> > iterations+1)
> >  else (iterations, x, y)
> > }
>
> > This is the generated code:
> > final def mandelbrotsetdesigner$FunctionIterator$$getIterations(x:
> > Double, y: Double, x_0: Double, y_0: Double, iterations: Int): Tuple3
> > = {
> >  <synthetic> val _$this: mandelbrotsetdesigner.FunctionIterator =
> > FunctionIterator.this;
> >  _getIterations(_$this,x,y,x_0,y_0,iterations){
> >    if (iterations.<(FunctionIterator.this.maxIterations()).&&(x.*(x).+
> > (y.*(y)).<=(4)))
> >      _getIterations(FunctionIterator.this, x.*(x).-(y.*(y)).+(x_0),
> > x.*(y).*(2.0).+(y_0), x_0, y_0, iterations.+(1))
> >    else
> >      new Tuple3(scala.Int.box(iterations), scala.Double.box(x),
> > scala.Double.box(y))
> >  }
> > };
>
> > ----------------------------------------------------
> > I tried this way as well, but it didn't work
>
> > case class SpecializedTupleT3 [@specialized(Int) TT1,
> >                                               @specialized(Double)
> > TT2,
> >                                               @specialized(Double)
> > TT3](_1:TT1, _2:TT2, _3:TT3)
> > private def getIterations(x:Double, y:Double, x_0:Double,
> >                          y_0:Double, iterations:
> > Int):SpecializedTupleT3[Int, Double,
> > Double] = {
> >  if (iterations < maxIterations && x*x + y*y <= 4)
> >    getIterations(x*x - y*y + x_0, x*y*2.0 + y_0, x_0, y_0, iterations
> > +1)
> >  else new SpecializedTupleT3[Int, Double, Double](iterations, x, y)
> > }
>
> > -------------
>
> > Thanks


H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: Re: How to avoid Int and Double boxing in a returned tuple

there should be no reason for primitive values to be boxed when used in case classes. go to yourkit.com and let the profiler show you where the problem is

-------- Original-Nachricht --------
> Datum: Mon, 2 Jan 2012 23:56:37 -0800
> Von: Ahaly Kumar
> An: Rex Kerr , scala-user
> CC: guast
> Betreff: Re: [scala-user] Re: How to avoid Int and Double boxing in a returned tuple ?

>
> How do we prevent auto-boxing when we used case classes? The case class
> instance would still be initiated with a Int or a Double - right?
> Also does this mean it is not recommended to use Int, Double etc in
> Tuples?
>
> - Ahaly "newbie" Kumar
>
>
> On Dec 31, 2011, at 10:06 PM, Rex Kerr wrote:
>
> > You're benchmarking wrong if you find that case classes are _slower_
> than tuples. (Unless there is some other source of boxing/unboxing and you're
> actually making it worse by storing primitives in case classes.)
> >
> > --Rex
> >
> > On Sat, Dec 31, 2011 at 8:38 AM, guast wrote:
> > Thanks for the answer.
> >
> > I tried again, but eventually to avoid the forced boxing I created my
> > own box and it was even slower.
> >
> > On Dec 31, 1:16 pm, Rex Kerr wrote:
> > > The specialized version should work (you were probably not looking at
> the
> > > SpecializedTuple3$mcIDD$sp class which is the specialized version that
> is
> > > generated and will be used if all the parameters match), but it's
> overkill
> > > for your application. Just use a case class--and then you can name
> your
> > > variables something sensible also!
> > >
> > > case class MbIter(i: Int, x: Double, y: Double) {}
> > > ...
> > > else MbIter(iterations, x, y)
> > > ...
> > >
> > > --Rex
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > > On Sat, Dec 31, 2011 at 6:16 AM, guast wrote:
> > > > Hi All
> > >
> > > > I have a method that returns a tuple of (Int, Double, Double). I am
> > > > returning some fields of the same type. However in the generated
> class
> > > > I can see that the value are boxed. That method will be called
> > > > millions of times so I am trying to optimize it as much as possible,
> > > > but I can't avoid the boxing. Is there a way to do it ?
> > >
> > > > This is the last version of the method:
> > >
> > > > private def getIterations(x:Double, y:Double, x_0:Double,
> > > > y_0:Double, iterations: Int):(Int, Double,
> > > > Double) = {
> > > > if (iterations < maxIterations && x*x + y*y <= 4)
> > > > getIterations(x*x - y*y + x_0, x*y*2.0 + y_0, x_0, y_0,
> > > > iterations+1)
> > > > else (iterations, x, y)
> > > > }
> > >
> > > > This is the generated code:
> > > > final def mandelbrotsetdesigner$FunctionIterator$$getIterations(x:
> > > > Double, y: Double, x_0: Double, y_0: Double, iterations: Int):
> Tuple3
> > > > = {
> > > > val _$this: mandelbrotsetdesigner.FunctionIterator =
> > > > FunctionIterator.this;
> > > > _getIterations(_$this,x,y,x_0,y_0,iterations){
> > > > if
> (iterations.<(FunctionIterator.this.maxIterations()).&&(x.*(x).+
> > > > (y.*(y)).<=(4)))
> > > > _getIterations(FunctionIterator.this, x.*(x).-(y.*(y)).+(x_0),
> > > > x.*(y).*(2.0).+(y_0), x_0, y_0, iterations.+(1))
> > > > else
> > > > new Tuple3(scala.Int.box(iterations), scala.Double.box(x),
> > > > scala.Double.box(y))
> > > > }
> > > > };
> > >
> > > > ----------------------------------------------------
> > > > I tried this way as well, but it didn't work
> > >
> > > > case class SpecializedTupleT3 [@specialized(Int) TT1,
> > > > @specialized(Double)
> > > > TT2,
> > > > @specialized(Double)
> > > > TT3](_1:TT1, _2:TT2, _3:TT3)
> > > > private def getIterations(x:Double, y:Double, x_0:Double,
> > > > y_0:Double, iterations:
> > > > Int):SpecializedTupleT3[Int, Double,
> > > > Double] = {
> > > > if (iterations < maxIterations && x*x + y*y <= 4)
> > > > getIterations(x*x - y*y + x_0, x*y*2.0 + y_0, x_0, y_0,
> iterations
> > > > +1)
> > > > else new SpecializedTupleT3[Int, Double, Double](iterations, x, y)
> > > > }
> > >
> > > > -------------
> > >
> > > > Thanks
> >
>

guast
Joined: 2010-12-31,
User offline. Last seen 1 year 36 weeks ago.
Re: How to avoid Int and Double boxing in a returned tuple ?

By "Didn't" work I meant that my attempt to improve the performance
got the opposite result.
Wrapping everything in a case class to be passed in the recursive call
slowed down two to three times the whole application.

Bye

On Jan 2, 12:25 am, Simon Ochsenreither
wrote:
> Hi,
>
> “it didn't work” -> Compile error? Runtime error? VM crash? Slow
> performance?
>
> Hint: Most people can't read minds.
>
> I'm pretty sure nobody can help you with that description.  :-)
>
> Bye

guast
Joined: 2010-12-31,
User offline. Last seen 1 year 36 weeks ago.
Re: How to avoid Int and Double boxing in a returned tuple ?

Actually I am not much more expert than you are.
What I can say is to be careful when the return type of a method is a
tuple with more than two parameters.
Usually boxing has a negligible impact, in my case I noticed it only
for this method because it is called a lot of time recursively. In any
case if the boxing affects the performance you can spot it quickly
with the VisualVM.
Furthermore, compiling with the -print option you can find easily
where boxing is used.
For the case classes the considerations are the same, you have to
worry only if the number of instances created is quite big.

Bye

On Jan 3, 8:56 am, Ahaly Kumar wrote:
> How do we prevent auto-boxing when we used case classes? The case class instance would still be initiated with a Int or a Double - right?
> Also does this mean it is not recommended to use Int, Double etc in Tuples?
>
> - Ahaly "newbie" Kumar
>

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: Re: How to avoid Int and Double boxing in a returned tuple
Tuple2 is specialized for Int, Long, and Double.  Tuple3 is not for anything.  Be equally careful about using Tuple2 with entries that are not Int, Long, or Double.  Or use a case class, which despite guast's benchmarking, are every bit as fast as Tuple2 if you make them do exactly the same thing.  (E.g. case class Two(i: Int, d: Double) is just as fast as the equivalent tuple, if you use it exactly the same way; case class Two(i: Int, b: Byte) is faster, since the case class uses primitives but Tuple2 is not specialized for Byte so it does not.)

  --Rex

On Tue, Jan 3, 2012 at 7:52 AM, guast <v [dot] guast [at] gmail [dot] com> wrote:
Actually I am not much more expert than you are.
What I can say is to be careful when the return type of a method is a
tuple with more than two parameters.
Usually boxing has a negligible impact, in my case I noticed it only
for this method because it is called a lot of time recursively. In any
case if the boxing affects the performance you can spot it quickly
with the VisualVM.
Furthermore, compiling with the -print option you can find easily
where boxing is used.
For the case classes the considerations are the same, you have to
worry only if the number of instances created is quite big.

Bye

On Jan 3, 8:56 am, Ahaly Kumar <ahaly [dot] ku [dot] [dot] [dot] [at] gmail [dot] com> wrote:
> How do we prevent auto-boxing when we used case classes? The case class instance would still be initiated with a Int or a Double - right?
> Also does this mean it is not recommended to use Int, Double etc in Tuples?
>
> - Ahaly "newbie" Kumar
>

d_m
Joined: 2010-11-11,
User offline. Last seen 35 weeks 2 days ago.
Re: Re: How to avoid Int and Double boxing in a returned tuple

On Tue, Jan 03, 2012 at 12:13:03PM -0500, Rex Kerr wrote:
> Tuple2 is specialized for Int, Long, and Double. Tuple3 is not for
> anything. Be equally careful about using Tuple2 with entries that are not
> Int, Long, or Double. Or use a case class, which despite guast's
> benchmarking, are every bit as fast as Tuple2 if you make them do exactly
> the same thing. (E.g. case class Two(i: Int, d: Double) is just as fast as
> the equivalent tuple, if you use it exactly the same way; case class Two(i:
> Int, b: Byte) is faster, since the case class uses primitives but Tuple2 is
> not specialized for Byte so it does not.)

Just to expand upon Rex's explanation:

Since Tupl2 isn't specialized on AnyRef, you even have to be careful
about doing Tuple2[Int, MyBoxedClass]. Even though MyBoxedClass isn't
an AnyVal type (e.g. it doesn't need boxing) you will still end up
boxing your Int.

This is yet another advantage of case classes.

Aside: In my opinion any of the types in Scala's standard library which
are specialized on two type parameters should be specialized on AnyRef,
if only to avoid problems like this (which are pretty counter-intuitive
until you understand how @specalized is implemented).

Ismael Juma 2
Joined: 2011-01-22,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: How to avoid Int and Double boxing in a returned tuple
On Tue, Jan 3, 2012 at 6:35 PM, Erik Osheim <erik [at] plastic-idolatry [dot] com> wrote:
Aside: In my opinion any of the types in Scala's standard library which are specialized on two type parameters should be specialized on AnyRef,
if only to avoid problems like this (which are pretty counter-intuitive
until you understand how @specalized is implemented).

Agreed.
Best,Ismael
ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: Re: How to avoid Int and Double boxing in a returned tuple
I agree also, but I should point out that the specialization on AnyRef is even buggier than regular specialization.
  --Rex

On Tue, Jan 3, 2012 at 1:43 PM, Ismael Juma <ismael [at] juma [dot] me [dot] uk> wrote:
On Tue, Jan 3, 2012 at 6:35 PM, Erik Osheim <erik [at] plastic-idolatry [dot] com> wrote:
Aside: In my opinion any of the types in Scala's standard library which are specialized on two type parameters should be specialized on AnyRef,
if only to avoid problems like this (which are pretty counter-intuitive
until you understand how @specalized is implemented).

Agreed.
Best,Ismael

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland