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

math.max(a, b, c)

40 replies
Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
I hesitate to bring this up because it is so trivial, but wouldn't it make sense for the min and max functions in scala.math to accept more than two arguments? Why not change this:

def max(x: Int, y: Int): Int

to this:

def max(x: Int*): Int

or, to force at least one argument:

def max(x: Int, y: Int*): Int

Yes, I realize there are simple ways to accomplish the same thing (e.g., List(a, b, c).max), but this would be convenient in some instances, and I assume it is trivial to implement. I have had occasion to find the min or max of three or more numbers.

While we're at it, how about

def mean(x: Double*): Double

Russ P.

--
http://RussP.us
Chris Marshall
Joined: 2009-06-17,
User offline. Last seen 44 weeks 3 days ago.
RE: math.max(a, b, c)
I don't think that this will be popular with those who prefer performance given the array/sequence creation overhead; although arguably they are in the minority and could roll their own functions.
Chris

Date: Fri, 7 Jan 2011 11:13:22 -0800
Subject: [scala-debate] math.max(a, b, c)
From: russ.paielli@gmail.com
To: scala-debate@listes.epfl.ch

I hesitate to bring this up because it is so trivial, but wouldn't it make sense for the min and max functions in scala.math to accept more than two arguments? Why not change this:

def max(x: Int, y: Int): Int

to this:

def max(x: Int*): Int

or, to force at least one argument:

def max(x: Int, y: Int*): Int

Yes, I realize there are simple ways to accomplish the same thing (e.g., List(a, b, c).max), but this would be convenient in some instances, and I assume it is trivial to implement. I have had occasion to find the min or max of three or more numbers.

While we're at it, how about

def mean(x: Double*): Double

Russ P.

--
http://RussP.us
Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: RE: math.max(a, b, c)


On 7 Jan 2011 19:18, "Chris Marshall" <oxbow_lakes@hotmail.com> wrote:
>
> I don't think that this will be popular with those who prefer performance given the array/sequence creation overhead; although arguably they are in the minority and could roll their own functions.
>
> Chris
>

I'd say the opposite is true. If you want this functionality then just use a fold, or Seq#max

> ________________________________
> Date: Fri, 7 Jan 2011 11:13:22 -0800
> Subject: [scala-debate] math.max(a, b, c)
> From: russ.paielli@gmail.com
> To: scala-debate@listes.epfl.ch
>
>
> I hesitate to bring this up because it is so trivial, but wouldn't it make sense for the min and max functions in scala.math to accept more than two arguments? Why not change this:
>
> def max(x: Int, y: Int): Int
>
> to this:
>
> def max(x: Int*): Int
>
> or, to force at least one argument:
>
> def max(x: Int, y: Int*): Int
>
> Yes, I realize there are simple ways to accomplish the same thing (e.g., List(a, b, c).max), but this would be convenient in some instances, and I assume it is trivial to implement. I have had occasion to find the min or max of three or more numbers.
>
> While we're at it, how about
>
> def mean(x: Double*): Double
>
> Russ P.
>
> --
> http://RussP.us

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: math.max(a, b, c)
I would prefer to have an entire numeric library a la Apache Commons math (not all of it, perhaps, but a reasonable subset).  Simply adding a max function alone does not seem to me to solve a significant number of problems since it is so easy to implement (unlike, e.g. the lnGamma function), and having it take varargs instead of an array (with possible slicing) is not obviously the way to go for performance.

  --Rex

On Fri, Jan 7, 2011 at 2:13 PM, Russ Paielli <russ.paielli@gmail.com> wrote:
I hesitate to bring this up because it is so trivial, but wouldn't it make sense for the min and max functions in scala.math to accept more than two arguments? Why not change this:

def max(x: Int, y: Int): Int

to this:

def max(x: Int*): Int

or, to force at least one argument:

def max(x: Int, y: Int*): Int

Yes, I realize there are simple ways to accomplish the same thing (e.g., List(a, b, c).max), but this would be convenient in some instances, and I assume it is trivial to implement. I have had occasion to find the min or max of three or more numbers.

While we're at it, how about

def mean(x: Double*): Double

Russ P.

--
http://RussP.us

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: math.max(a, b, c)
It is not without consequence:

scala> object M {
     |   def max(xs: Int*) = xs.reduceLeft(_ max _)
     | }
defined module M

scala> List(1, 2, 3, 4, 5).reduceLeft(math.max)
res31: Int = 5

scala> List(1, 2, 3, 4, 5).reduceLeft(M.max)  
<console>:11: error: type mismatch;
 found   : (Int*) => Int
 required: (?, Int) => ?
       List(1, 2, 3, 4, 5).reduceLeft(M.max)
                                        ^


On Fri, Jan 7, 2011 at 17:13, Russ Paielli <russ.paielli@gmail.com> wrote:
I hesitate to bring this up because it is so trivial, but wouldn't it make sense for the min and max functions in scala.math to accept more than two arguments? Why not change this:

def max(x: Int, y: Int): Int

to this:

def max(x: Int*): Int

or, to force at least one argument:

def max(x: Int, y: Int*): Int

Yes, I realize there are simple ways to accomplish the same thing (e.g., List(a, b, c).max), but this would be convenient in some instances, and I assume it is trivial to implement. I have had occasion to find the min or max of three or more numbers.

While we're at it, how about

def mean(x: Double*): Double

Russ P.

--
http://RussP.us



--
Daniel C. Sobral

I travel to the future all the time.
Tony Morris 2
Joined: 2009-03-20,
User offline. Last seen 42 years 45 weeks ago.
Re: math.max(a, b, c)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 08/01/11 05:23, Kevin Wright wrote:
>
>
> On 7 Jan 2011 19:18, "Chris Marshall" <oxbow_lakes@hotmail.com
> > wrote:
>>
>> I don't think that this will be popular with those who prefer
> performance given the array/sequence creation overhead; although
> arguably they are in the minority and could roll their own
> functions.
>>
>> Chris
>>
>
> I'd say the opposite is true. If you want this functionality then
> just use a fold, or Seq#max
>
>
Abstract on the type constructor.

Scalaz has this.
https://github.com/scalaz/scalaz/blob/master/core/src/main/scala/scalaz/MA.scala#L134

- --
Tony Morris
http://tmorris.net/

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk0nb1kACgkQmnpgrYe6r62LVwCfQyHVYxvsnn0H7BWCp8qqWvD4
DRwAoKIl7nOQ+O7O/z/pEvIqOT7ux1ok
=ehCq
-----END PGP SIGNATURE-----

Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
Re: math.max(a, b, c)
On Fri, Jan 7, 2011 at 11:19 AM, Daniel Sobral <dcsobral@gmail.com> wrote:
It is not without consequence:

scala> object M {
     |   def max(xs: Int*) = xs.reduceLeft(_ max _)
     | }
defined module M

scala> List(1, 2, 3, 4, 5).reduceLeft(math.max)
res31: Int = 5

scala> List(1, 2, 3, 4, 5).reduceLeft(M.max)  
<console>:11: error: type mismatch;
 found   : (Int*) => Int
 required: (?, Int) => ?
       List(1, 2, 3, 4, 5).reduceLeft(M.max)
                                        ^
I think you've shown that you would lose the ability to use min or max as infix operators. Frankly, I didn't even know that was possible. Nor can I think of a reason that I would ever want to do it. If I am missing an important use case, please let me know.

Russ P.

--
http://RussP.us
Razvan Cojocaru 3
Joined: 2010-07-28,
User offline. Last seen 42 years 45 weeks ago.
Re: math.max(a, b, c)
I think the point is that you can no longer use it in folds, sorts etc without an intermediary lambda, thus potentially breaking tons of existing code. 

Thanks,Razvan
On 2011-01-07, at 3:07 PM, Russ Paielli <russ.paielli@gmail.com> wrote:

On Fri, Jan 7, 2011 at 11:19 AM, Daniel Sobral < (dcsobral [at] gmail [dot] com> wrote:
It is not without consequence:

scala> object M {
     |   def max(xs: Int*) = xs.reduceLeft(_ max _)
     | }
defined module M

scala> List(1, 2, 3, 4, 5).reduceLeft(math.max)
res31: Int = 5

scala> List(1, 2, 3, 4, 5).reduceLeft(M.max)  
<console>:11: error: type mismatch;
 found   : (Int*) => Int
 required: (?, Int) => ?
       List(1, 2, 3, 4, 5).reduceLeft(M.max)
                                        ^
I think you've shown that you would lose the ability to use min or max as infix operators. Frankly, I didn't even know that was possible. Nor can I think of a reason that I would ever want to do it. If I am missing an important use case, please let me know.

Russ P.

--
http://RussP.us
H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: math.max(a, b, c)
one could define max(a,b,c*) in addition to the existing max(a,b)

Am 09.01.2011 14:37, schrieb Razvan Cojocaru:
FDA663AD-8200-4BBE-8566-6DC4DA260602 [at] razie [dot] com" type="cite"> I think the point is that you can no longer use it in folds, sorts etc without an intermediary lambda, thus potentially breaking tons of existing code. 

Thanks, Razvan
On 2011-01-07, at 3:07 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com" rel="nofollow">russ.paielli@gmail.com> wrote:

On Fri, Jan 7, 2011 at 11:19 AM, Daniel Sobral <dcsobral [at] gmail [dot] com" rel="nofollow">dcsobral@gmail.com> wrote:
It is not without consequence:

scala> object M {
     |   def max(xs: Int*) = xs.reduceLeft(_ max _)
     | }
defined module M

scala> List(1, 2, 3, 4, 5).reduceLeft(math.max)
res31: Int = 5

scala> List(1, 2, 3, 4, 5).reduceLeft(M.max)  
<console>:11: error: type mismatch;
 found   : (Int*) => Int
 required: (?, Int) => ?
       List(1, 2, 3, 4, 5).reduceLeft(M.max)
                                        ^
I think you've shown that you would lose the ability to use min or max as infix operators. Frankly, I didn't even know that was possible. Nor can I think of a reason that I would ever want to do it. If I am missing an important use case, please let me know.

Russ P.

--
http://RussP.us

Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: math.max(a, b, c)


On 9 January 2011 13:53, HamsterofDeath <h-star@gmx.de> wrote:
one could define max(a,b,c*) in addition to the existing max(a,b)


Overloading comes with its own unique issues though, so I wouldn't be too hasty in doing this.
 
Am 09.01.2011 14:37, schrieb Razvan Cojocaru:
I think the point is that you can no longer use it in folds, sorts etc without an intermediary lambda, thus potentially breaking tons of existing code. 

Thanks, Razvan
On 2011-01-07, at 3:07 PM, Russ Paielli <russ.paielli@gmail.com> wrote:

On Fri, Jan 7, 2011 at 11:19 AM, Daniel Sobral <dcsobral@gmail.com> wrote:
It is not without consequence:

scala> object M {
     |   def max(xs: Int*) = xs.reduceLeft(_ max _)
     | }
defined module M

scala> List(1, 2, 3, 4, 5).reduceLeft(math.max)
res31: Int = 5

scala> List(1, 2, 3, 4, 5).reduceLeft(M.max)  
<console>:11: error: type mismatch;
 found   : (Int*) => Int
 required: (?, Int) => ?
       List(1, 2, 3, 4, 5).reduceLeft(M.max)
                                        ^
I think you've shown that you would lose the ability to use min or max as infix operators. Frankly, I didn't even know that was possible. Nor can I think of a reason that I would ever want to do it. If I am missing an important use case, please let me know.

Russ P.

--
http://RussP.us




--
Kevin Wright

gtalk / msn : kev.lee.wright@gmail.comkev.lee.wright@gmail.commail: kevin.wright@scalatechnology.com
vibe / skype: kev.lee.wright
twitter: @thecoda

H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: math.max(a, b, c)
give it another name: maxOf(a,b*) :D

Am 09.01.2011 15:18, schrieb Kevin Wright:
KhC94s_ [at] mail [dot] gmail [dot] com" type="cite">

On 9 January 2011 13:53, HamsterofDeath <h-star [at] gmx [dot] de" rel="nofollow">h-star@gmx.de> wrote:
one could define max(a,b,c*) in addition to the existing max(a,b)


Overloading comes with its own unique issues though, so I wouldn't be too hasty in doing this.
 
Am 09.01.2011 14:37, schrieb Razvan Cojocaru:
I think the point is that you can no longer use it in folds, sorts etc without an intermediary lambda, thus potentially breaking tons of existing code. 

Thanks, Razvan
On 2011-01-07, at 3:07 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com" target="_blank" rel="nofollow">russ.paielli@gmail.com> wrote:

On Fri, Jan 7, 2011 at 11:19 AM, Daniel Sobral <dcsobral [at] gmail [dot] com" target="_blank" rel="nofollow">dcsobral@gmail.com> wrote:
It is not without consequence:

scala> object M {
     |   def max(xs: Int*) = xs.reduceLeft(_ max _)
     | }
defined module M

scala> List(1, 2, 3, 4, 5).reduceLeft(math.max)
res31: Int = 5

scala> List(1, 2, 3, 4, 5).reduceLeft(M.max)  
<console>:11: error: type mismatch;
 found   : (Int*) => Int
 required: (?, Int) => ?
       List(1, 2, 3, 4, 5).reduceLeft(M.max)
                                        ^
I think you've shown that you would lose the ability to use min or max as infix operators. Frankly, I didn't even know that was possible. Nor can I think of a reason that I would ever want to do it. If I am missing an important use case, please let me know.

Russ P.

--
http://RussP.us




--
Kevin Wright

gtalk / msn : kev [dot] lee [dot] wright [at] gmail [dot] com" target="_blank" rel="nofollow">kev.lee.wright@gmail.com mail: kevin [dot] wright [at] scalatechnology [dot] com" target="_blank" rel="nofollow">kevin.wright@scalatechnology.com
vibe / skype: kev.lee.wright
twitter: @thecoda


nilskp
Joined: 2009-01-30,
User offline. Last seen 1 year 27 weeks ago.
Re: math.max(a, b, c)
On Sun, Jan 9, 2011 at 8:18 AM, Kevin Wright <kev.lee.wright@gmail.com> wrote:


On 9 January 2011 13:53, HamsterofDeath <h-star@gmx.de> wrote:
one could define max(a,b,c*) in addition to the existing max(a,b)


Overloading comes with its own unique issues though, so I wouldn't be too hasty in doing this.

You mean in general, or for the specific case given?
Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: math.max(a, b, c)


On 9 January 2011 15:10, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:
On Sun, Jan 9, 2011 at 8:18 AM, Kevin Wright <kev.lee.wright@gmail.com> wrote:


On 9 January 2011 13:53, HamsterofDeath <h-star@gmx.de> wrote:
one could define max(a,b,c*) in addition to the existing max(a,b)


Overloading comes with its own unique issues though, so I wouldn't be too hasty in doing this.

You mean in general, or for the specific case given?

In general.  It's like going overboard on inheritance, I find that avoiding it tends to leads towards better designs.


--
Kevin Wright

gtalk / msn : kev.lee.wright@gmail.com kev.lee.wright@gmail.commail: kevin.wright@scalatechnology.com
vibe / skype: kev.lee.wright
twitter: @thecoda

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: math.max(a, b, c)
I don't see the need for n-ary max, given that we have infix max.

math.max(1, 2, 3)

would be neither shorter nor more legible or more efficient than

1 max 2 max 3

Cheers

 -- Martin


H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: math.max(a, b, c)

you win, i forgot that one. i answered hastily.

Am 09.01.2011 16:35, schrieb martin odersky:
> I don't see the need for n-ary max, given that we have infix max.
>
> math.max(1, 2, 3)
>
> would be neither shorter nor more legible or more efficient than
>
> 1 max 2 max 3
>
> Cheers
>

nilskp
Joined: 2009-01-30,
User offline. Last seen 1 year 27 weeks ago.
Re: math.max(a, b, c)
On Sun, Jan 9, 2011 at 9:35 AM, martin odersky <martin.odersky@epfl.ch> wrote:
I don't see the need for n-ary max, given that we have infix max.

math.max(1, 2, 3)

would be neither shorter nor more legible or more efficient than

1 max 2 max 3

Doesn't the infix require the construction of a RichInt on every invocation, or is infix max compiler optimized?
H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: math.max(a, b, c)
afaik the vm should be able to optimize the allocation away (escape analysis). but i never tested it.

Am 09.01.2011 18:35, schrieb Nils Kilden-Pedersen:
AANLkTinXU90BHNpw0EBYY-oQJCyEtHg6ehJFtP-5QjqQ [at] mail [dot] gmail [dot] com" type="cite"> On Sun, Jan 9, 2011 at 9:35 AM, martin odersky <martin [dot] odersky [at] epfl [dot] ch" rel="nofollow">martin.odersky@epfl.ch> wrote:
I don't see the need for n-ary max, given that we have infix max.

math.max(1, 2, 3)

would be neither shorter nor more legible or more efficient than

1 max 2 max 3

Doesn't the infix require the construction of a RichInt on every invocation, or is infix max compiler optimized?

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: math.max(a, b, c)
Rich max is not free, even with escape analysis:

java -XX:+DoEscapeAnalysis -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 1.612 seconds
  Checksum = 661242756
Prefix Elapsed: 0.929 seconds
  Checksum = 661242756
If Elapsed: 0.929 seconds
  Checksum = 661242756

java -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 4.574 seconds
  Checksum = 661242756
Prefix Elapsed: 0.922 seconds
  Checksum = 661242756
If Elapsed: 0.922 seconds
  Checksum = 661242756

Infix is (i max j), prefix is math.max(i,j), and if is (if (i<j) j else i).  (Code attached.)

Max of three shows exactly what you'd expect given the results for two.

  --Rex



On Sun, Jan 9, 2011 at 1:00 PM, HamsterofDeath <h-star@gmx.de> wrote:
afaik the vm should be able to optimize the allocation away (escape analysis). but i never tested it.

Am 09.01.2011 18:35, schrieb Nils Kilden-Pedersen:
On Sun, Jan 9, 2011 at 9:35 AM, martin odersky <martin.odersky@epfl.ch> wrote:
I don't see the need for n-ary max, given that we have infix max.

math.max(1, 2, 3)

would be neither shorter nor more legible or more efficient than

1 max 2 max 3

Doesn't the infix require the construction of a RichInt on every invocation, or is infix max compiler optimized?


Tony Morris 2
Joined: 2009-03-20,
User offline. Last seen 42 years 45 weeks ago.
Re: math.max(a, b, c)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 09/01/11 23:53, HamsterofDeath wrote:
> one could define max(a,b,c*) in addition to the existing max(a,b)
>

It can be generalised.

trait Semigroup[A] {
    def app(a1: A, a2: A): A

     def fold1[F[_]](as: F[A])(f: Foldable[F]): A =
        as.reduceRight(app)
}

case class Max(n: Int)

object Semigroup {
    implicit def MaxSemigroup = new Semigroup[Max] {
        def app(a1: Max, a2: Max) = Max(a1.n max a2.n)

        def fold1[F[_]](as: F[Max])(implicit f: Foldable[F]): Max =
            as.reduceLeft(app) // optimised
    }
}

- --
Tony Morris
http://tmorris.net/

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk0qH/sACgkQmnpgrYe6r61zKwCfaMhnVXRI/8HmPvlly7ju6vCK
7ukAn0H553GcJO3mzt1WoMIOvQ3x/qaQ
=vy/V
-----END PGP SIGNATURE-----

H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: math.max(a, b, c)
same here, except that the code gets executed faster in the first 2 iterations, then becomes slower. no idea why.
the infix version is probably slower because of some random overhead that's left after optimizing the object allocations away. -verbose:gc doesn't print anything at all.

Iteration 1
Infix Elapsed: 1,491 seconds
  Checksum = 661242756
Prefix Elapsed: 0,855 seconds
  Checksum = 661242756
If Elapsed: 1,168 seconds
  Checksum = 661242756

Iteration 2
Infix Elapsed: 1,484 seconds
  Checksum = 661242756
Prefix Elapsed: 0,853 seconds
  Checksum = 661242756
If Elapsed: 1,167 seconds
  Checksum = 661242756

Iteration 3
Infix Elapsed: 1,666 seconds
  Checksum = 661242756
Prefix Elapsed: 0,848 seconds
  Checksum = 661242756
If Elapsed: 0,847 seconds
  Checksum = 661242756

Iteration 4
Infix Elapsed: 1,668 seconds
  Checksum = 661242756
Prefix Elapsed: 0,847 seconds
  Checksum = 661242756
If Elapsed: 0,847 seconds
  Checksum = 661242756

Iteration 5
Infix Elapsed: 1,667 seconds
  Checksum = 661242756
Prefix Elapsed: 0,848 seconds
  Checksum = 661242756
If Elapsed: 0,846 seconds
  Checksum = 661242756

Iteration 6
Infix Elapsed: 1,665 seconds
  Checksum = 661242756
Prefix Elapsed: 0,847 seconds
  Checksum = 661242756
If Elapsed: 0,848 seconds
  Checksum = 661242756


Am 09.01.2011 20:29, schrieb Rex Kerr:
VE3mLv4pP1Kn4+X0NJkaNuBtuQo [at] mail [dot] gmail [dot] com" type="cite">Rich max is not free, even with escape analysis:

java -XX:+DoEscapeAnalysis -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 1.612 seconds
  Checksum = 661242756
Prefix Elapsed: 0.929 seconds
  Checksum = 661242756
If Elapsed: 0.929 seconds
  Checksum = 661242756

java -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 4.574 seconds
  Checksum = 661242756
Prefix Elapsed: 0.922 seconds
  Checksum = 661242756
If Elapsed: 0.922 seconds
  Checksum = 661242756

Infix is (i max j), prefix is math.max(i,j), and if is (if (i<j) j else i).  (Code attached.)

Max of three shows exactly what you'd expect given the results for two.

  --Rex



On Sun, Jan 9, 2011 at 1:00 PM, HamsterofDeath <h-star [at] gmx [dot] de" rel="nofollow">h-star@gmx.de> wrote:
afaik the vm should be able to optimize the allocation away (escape analysis). but i never tested it.

Am 09.01.2011 18:35, schrieb Nils Kilden-Pedersen:
On Sun, Jan 9, 2011 at 9:35 AM, martin odersky <martin [dot] odersky [at] epfl [dot] ch" target="_blank" rel="nofollow">martin.odersky@epfl.ch> wrote:
I don't see the need for n-ary max, given that we have infix max.

math.max(1, 2, 3)

would be neither shorter nor more legible or more efficient than

1 max 2 max 3

Doesn't the infix require the construction of a RichInt on every invocation, or is infix max compiler optimized?



Erik Engbrecht
Joined: 2008-12-19,
User offline. Last seen 3 years 18 weeks ago.
Re: math.max(a, b, c)
If I understand correctly, Escape Analysis does not optimize away creation of the object.  It optimizes away allocation to the heap.  So there's still a trace amount of overhead left to create the object.

Initial iterations may be faster because HotSpot might encounter something that causes it to de-optimize a piece of code.  It does that surprisingly often.

On Sun, Jan 9, 2011 at 4:07 PM, HamsterofDeath <h-star@gmx.de> wrote:
same here, except that the code gets executed faster in the first 2 iterations, then becomes slower. no idea why.
the infix version is probably slower because of some random overhead that's left after optimizing the object allocations away. -verbose:gc doesn't print anything at all.

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: math.max(a, b, c)
It's not garbage collection.  Watch the output of the compiler with -XX:+PrintCompilation
  --Rex

On Sun, Jan 9, 2011 at 4:07 PM, HamsterofDeath <h-star@gmx.de> wrote:
same here, except that the code gets executed faster in the first 2 iterations, then becomes slower. no idea why.
the infix version is probably slower because of some random overhead that's left after optimizing the object allocations away. -verbose:gc doesn't print anything at all.

Iteration 1
Infix Elapsed: 1,491 seconds
  Checksum = 661242756
Prefix Elapsed: 0,855 seconds
  Checksum = 661242756
If Elapsed: 1,168 seconds
  Checksum = 661242756

Iteration 2
Infix Elapsed: 1,484 seconds
  Checksum = 661242756
Prefix Elapsed: 0,853 seconds
  Checksum = 661242756
If Elapsed: 1,167 seconds
  Checksum = 661242756

Iteration 3
Infix Elapsed: 1,666 seconds
  Checksum = 661242756
Prefix Elapsed: 0,848 seconds
  Checksum = 661242756
If Elapsed: 0,847 seconds
  Checksum = 661242756

Iteration 4
Infix Elapsed: 1,668 seconds
  Checksum = 661242756
Prefix Elapsed: 0,847 seconds
  Checksum = 661242756
If Elapsed: 0,847 seconds
  Checksum = 661242756

Iteration 5
Infix Elapsed: 1,667 seconds
  Checksum = 661242756
Prefix Elapsed: 0,848 seconds
  Checksum = 661242756
If Elapsed: 0,846 seconds
  Checksum = 661242756

Iteration 6
Infix Elapsed: 1,665 seconds
  Checksum = 661242756
Prefix Elapsed: 0,847 seconds
  Checksum = 661242756
If Elapsed: 0,848 seconds
  Checksum = 661242756


Am 09.01.2011 20:29, schrieb Rex Kerr:
Rich max is not free, even with escape analysis:

java -XX:+DoEscapeAnalysis -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 1.612 seconds
  Checksum = 661242756
Prefix Elapsed: 0.929 seconds
  Checksum = 661242756
If Elapsed: 0.929 seconds
  Checksum = 661242756

java -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 4.574 seconds
  Checksum = 661242756
Prefix Elapsed: 0.922 seconds
  Checksum = 661242756
If Elapsed: 0.922 seconds
  Checksum = 661242756

Infix is (i max j), prefix is math.max(i,j), and if is (if (i<j) j else i).  (Code attached.)

Max of three shows exactly what you'd expect given the results for two.

  --Rex



On Sun, Jan 9, 2011 at 1:00 PM, HamsterofDeath <h-star@gmx.de> wrote:
afaik the vm should be able to optimize the allocation away (escape analysis). but i never tested it.

Am 09.01.2011 18:35, schrieb Nils Kilden-Pedersen:
On Sun, Jan 9, 2011 at 9:35 AM, martin odersky <martin.odersky@epfl.ch> wrote:
I don't see the need for n-ary max, given that we have infix max.

math.max(1, 2, 3)

would be neither shorter nor more legible or more efficient than

1 max 2 max 3

Doesn't the infix require the construction of a RichInt on every invocation, or is infix max compiler optimized?




Jesper Nordenberg
Joined: 2008-12-27,
User offline. Last seen 42 years 45 weeks ago.
Re: math.max(a, b, c)

When Hotspot determines that an object doesn't escape the method under
optimization, it can, in some cases, place it's field values in local
variables (registers or stack). The optimized code is then as fast as
code written without any object allocation.

Unfortunately there are cases which Hotspots EA is lacking and it won't
apply the heap allocation elimination optimization even though it's
clearly applicable. I suggest using the latest Java version and
benchmarking the same code with and without object allocation. It's easy
to see if there is any heap allocation using a tool like VisualVM.

/Jesper Nordenberg

Erik Engbrecht skrev 2011-01-09 22:24:
> If I understand correctly, Escape Analysis does not optimize away
> creation of the object. It optimizes away allocation to the heap. So
> there's still a trace amount of overhead left to create the object.
>
> Initial iterations may be faster because HotSpot might encounter
> something that causes it to de-optimize a piece of code. It does that
> surprisingly often.
>
> On Sun, Jan 9, 2011 at 4:07 PM, HamsterofDeath > wrote:
>
> same here, except that the code gets executed faster in the first 2
> iterations, then becomes slower. no idea why.
> the infix version is probably slower because of some random overhead
> that's left after optimizing the object allocations away.
> -verbose:gc doesn't print anything at all.
>
>

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: math.max(a, b, c)


On Sun, Jan 9, 2011 at 8:29 PM, Rex Kerr <ichoran@gmail.com> wrote:
Rich max is not free, even with escape analysis:

java -XX:+DoEscapeAnalysis -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 1.612 seconds
  Checksum = 661242756
Prefix Elapsed: 0.929 seconds
  Checksum = 661242756
If Elapsed: 0.929 seconds
  Checksum = 661242756

java -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 4.574 seconds
  Checksum = 661242756
Prefix Elapsed: 0.922 seconds
  Checksum = 661242756
If Elapsed: 0.922 seconds
  Checksum = 661242756

Infix is (i max j), prefix is math.max(i,j), and if is (if (i<j) j else i).  (Code attached.)

Are these the numbers with -optimize on?

Cheers

 -- Martin

Aydjen
Joined: 2009-08-21,
User offline. Last seen 1 year 28 weeks ago.
Re: math.max(a, b, c)

Rex Kerr wrote:

> Rich max is not free, even with escape analysis:
>
> java -XX:+DoEscapeAnalysis -cp
> /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
> //(warmup elided)
> Iteration 3
> Infix Elapsed: 1.612 seconds
>   Checksum = 661242756
> Prefix Elapsed: 0.929 seconds
>   Checksum = 661242756
> If Elapsed: 0.929 seconds
>   Checksum = 661242756
>
> java -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
> //(warmup elided)
> Iteration 3
> Infix Elapsed: 4.574 seconds
>   Checksum = 661242756
> Prefix Elapsed: 0.922 seconds
>   Checksum = 661242756
> If Elapsed: 0.922 seconds
>   Checksum = 661242756
>
> Infix is (i max j), prefix is math.max(i,j), and if is (if (i

Which VM version did you use? In the JDK6 update 23 (on Windows), the
escape analysis option is only available (and switched on by default) in
the server VM, but I do not see the "-server" flag in your call to
"java", which should fail to start the VM with update 23...

Aydjen
Joined: 2009-08-21,
User offline. Last seen 1 year 28 weeks ago.
Re: math.max(a, b, c)

Rex Kerr wrote:
> Rich max is not free, even with escape analysis:
>
> java -XX:+DoEscapeAnalysis -cp
> /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
> //(warmup elided)
> Iteration 3
> Infix Elapsed: 1.612 seconds
>   Checksum = 661242756
> Prefix Elapsed: 0.929 seconds
>   Checksum = 661242756
> If Elapsed: 0.929 seconds
>   Checksum = 661242756

Surprisingly (to me), the benchmark results change a lot if you use
longs everywhere:
http://paste.pocoo.org/show/318160/

java -server -cp "E:\scala\lib\scala-library.jar;." TwoMax

Iteration 3
Infix Elapsed: 5,533 seconds
Checksum = 3338615082255021824
Prefix Elapsed: 5,813 seconds
Checksum = 3338615082255021824
If Elapsed: 5,860 seconds
Checksum = 3338615082255021824

java version "1.6.0_23"
Java(TM) SE Runtime Environment (build 1.6.0_23-b05)
Java HotSpot(TM) Server VM (build 19.0-b09, mixed mode)

Ran on a 32-Bit OS and VM, maybe that has to do with it.

It did not matter whether I compiled with "-optimise" or not.

Kind regards
Andreas

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: math.max(a, b, c)

On Mon, Jan 10, 2011 at 09:23:19AM +0100, martin odersky wrote:
> Are these the numbers with -optimize on?

Looking at the bytecode, it won't make any difference. The only
nontrivial difference I see anywhere with and without -optimise is it
going nuts inlining ranges into the main method. Which, tangentially,
seems of uncertain utility. In the past I've found that sort of
inlining slower if anything.

// regular style
public void main(java.lang.String[]);
Code:
Stack=3, Locals=2, Args_size=2
0: getstatic #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
3: iconst_1
4: invokevirtual #69; //Method scala/Predef$.intWrapper:(I)Lscala/runtime/RichInt;
7: iconst_3
8: invokevirtual #95; //Method scala/runtime/RichInt.to:(I)Lscala/collection/immutable/Range$Inclusive;
11: new #97; //class TwoMax$$anonfun$main$1
14: dup
15: invokespecial #98; //Method TwoMax$$anonfun$main$1."":()V
18: invokevirtual #ccc; //Method scala/collection/immutable/Range$Inclusive.foreach:(Lscala/Function1;)V
21: return

// optimiZed style
public void main(java.lang.String[]);
Code:
Stack=10, Locals=33, Args_size=2
0: new #71; //class scala/runtime/RichInt
3: dup
4: iconst_1
5: invokespecial #94; //Method scala/runtime/RichInt."":(I)V
8: invokevirtual #97; //Method scala/runtime/RichInt.self:()I
11: istore_3
12: new #99; //class scala/collection/immutable/Range$Inclusive
15: dup
16: iload_3
17: iconst_3
18: iconst_1
19: invokespecial #888; //Method scala/collection/immutable/Range$Inclusive."":(III)V
22: new #ccc; //class TwoMax$$anonfun$main$1
25: dup
26: invokespecial #eee; //Method TwoMax$$anonfun$main$1."":()V
29: astore 29
31: dup
32: astore 31
34: invokevirtual #fff; //Method scala/collection/immutable/Range.length:()I
37: iconst_0
38: if_icmple 370
41: aload 31
43: invokevirtual #141414; //Method scala/collection/immutable/Range.last:()I
46: istore 4
48: aload 31
50: invokevirtual #1a1a1a; //Method scala/collection/immutable/Range.start:()I
53: istore 32
55: iload 32
57: iload 4
59: if_icmpne 371
62: iload 32
64: istore 6
66: new #1e1e1e; //class scala/collection/mutable/StringBuilder
69: dup
70: invokespecial #1f1f1f; //Method scala/collection/mutable/StringBuilder."":()V
73: ldc #1b1b1b; //String Iteration
75: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
78: iload 6
80: invokestatic #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
83: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
86: invokevirtual #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
89: astore 7
91: getstatic #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
94: aload 7
96: invokevirtual #303030; //Method scala/Console$.println:(Ljava/lang/Object;)V
99: getstatic #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
102: ldc #343434; //String Infix
104: invokevirtual #3a3a3a; //Method scala/Console$.print:(Ljava/lang/Object;)V
107: invokestatic #20; //Method java/lang/System.nanoTime:()J
110: lstore 8
112: getstatic #3e3e3e; //Field MODULE$:LTwoMax$;
115: invokevirtual #393939; //Method testInfix:()I
118: istore 11
120: getstatic #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
123: iconst_1
124: anewarray #36; //class java/lang/Object
127: dup
128: iconst_0
129: invokestatic #20; //Method java/lang/System.nanoTime:()J
132: lload 8
134: lsub
135: l2d
136: ldc2_w #37; //double 1.0E-9d
139: dmul
140: invokestatic #44; //Method scala/runtime/BoxesRunTime.boxToDouble:(D)Ljava/lang/Double;
143: aastore
144: invokevirtual #48; //Method scala/Predef$.genericWrapArray:(Ljava/lang/Object;)Lscala/collection/mutable/WrappedArray;
147: astore 10
149: getstatic #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
152: new #3c3c3c; //class scala/collection/immutable/StringOps
155: dup
156: ldc #34; //String Elapsed: %.3f seconds\n
158: invokespecial #424242; //Method scala/collection/immutable/StringOps."":(Ljava/lang/String;)V
161: aload 10
163: invokeinterface #454545, 2; //InterfaceMethod scala/collection/immutable/StringLike.format:(Lscala/collection/Seq;)Ljava/lang/String;
168: invokevirtual #3a3a3a; //Method scala/Console$.print:(Ljava/lang/Object;)V
171: iload 11
173: istore 12
175: new #1e1e1e; //class scala/collection/mutable/StringBuilder
178: dup
179: invokespecial #1f1f1f; //Method scala/collection/mutable/StringBuilder."":()V
182: ldc #484848; //String Checksum =
184: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
187: iload 12
189: invokestatic #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
192: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
195: invokevirtual #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
198: astore 13
200: getstatic #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
203: aload 13
205: invokevirtual #303030; //Method scala/Console$.println:(Ljava/lang/Object;)V
208: getstatic #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
211: ldc #4c4c4c; //String Prefix
213: invokevirtual #4e4e4e; //Method scala/Predef$.print:(Ljava/lang/Object;)V
216: new #525252; //class TwoMax$$anonfun$main$1$$anonfun$2
219: dup
220: aload 29
222: invokespecial #4f4f4f; //Method TwoMax$$anonfun$main$1$$anonfun$2."":(LTwoMax$$anonfun$main$1;)V
225: astore 14
227: invokestatic #20; //Method java/lang/System.nanoTime:()J
230: lstore 15
232: aload 14
234: invokevirtual #525252; //Method TwoMax$$anonfun$main$1$$anonfun$2.apply:()I
237: istore 17
239: getstatic #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
242: ldc #34; //String Elapsed: %.3f seconds\n
244: getstatic #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
247: iconst_1
248: anewarray #36; //class java/lang/Object
251: dup
252: iconst_0
253: invokestatic #20; //Method java/lang/System.nanoTime:()J
256: lload 15
258: lsub
259: l2d
260: ldc2_w #37; //double 1.0E-9d
263: dmul
264: invokestatic #44; //Method scala/runtime/BoxesRunTime.boxToDouble:(D)Ljava/lang/Double;
267: aastore
268: invokevirtual #48; //Method scala/Predef$.genericWrapArray:(Ljava/lang/Object;)Lscala/collection/mutable/WrappedArray;
271: invokevirtual #52; //Method scala/Predef$.printf:(Ljava/lang/String;Lscala/collection/Seq;)V
274: iload 17
276: istore 18
278: getstatic #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
281: new #1e1e1e; //class scala/collection/mutable/StringBuilder
284: dup
285: invokespecial #1f1f1f; //Method scala/collection/mutable/StringBuilder."":()V
288: ldc #484848; //String Checksum =
290: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
293: iload 18
295: invokestatic #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
298: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
301: invokevirtual #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
304: invokevirtual #545454; //Method scala/Predef$.println:(Ljava/lang/Object;)V
307: getstatic #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
310: ldc #585858; //String If
312: invokevirtual #4e4e4e; //Method scala/Predef$.print:(Ljava/lang/Object;)V
315: getstatic #3e3e3e; //Field MODULE$:LTwoMax$;
318: new #5c5c5c; //class TwoMax$$anonfun$main$1$$anonfun$3
321: dup
322: aload 29
324: invokespecial #555555; //Method TwoMax$$anonfun$main$1$$anonfun$3."":(LTwoMax$$anonfun$main$1;)V
327: invokevirtual #595959; //Method ptime:(Lscala/Function0;)Ljava/lang/Object;
330: invokestatic #606060; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
333: istore 19
335: getstatic #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
338: new #1e1e1e; //class scala/collection/mutable/StringBuilder
341: dup
342: invokespecial #1f1f1f; //Method scala/collection/mutable/StringBuilder."":()V
345: ldc #484848; //String Checksum =
347: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
350: iload 19
352: invokestatic #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
355: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
358: invokevirtual #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
361: invokevirtual #545454; //Method scala/Predef$.println:(Ljava/lang/Object;)V
364: getstatic #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
367: invokevirtual #646464; //Method scala/Console$.println:()V
370: return
371: iload 32
373: istore 21
375: new #1e1e1e; //class scala/collection/mutable/StringBuilder
378: dup
379: invokespecial #1f1f1f; //Method scala/collection/mutable/StringBuilder."":()V
382: ldc #1b1b1b; //String Iteration
384: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
387: iload 21
389: invokestatic #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
392: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
395: invokevirtual #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
398: astore 22
400: getstatic #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
403: aload 22
405: invokevirtual #303030; //Method scala/Console$.println:(Ljava/lang/Object;)V
408: getstatic #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
411: ldc #343434; //String Infix
413: invokevirtual #3a3a3a; //Method scala/Console$.print:(Ljava/lang/Object;)V
416: invokestatic #20; //Method java/lang/System.nanoTime:()J
419: lstore 23
421: getstatic #3e3e3e; //Field MODULE$:LTwoMax$;
424: invokevirtual #393939; //Method testInfix:()I
427: istore 26
429: getstatic #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
432: iconst_1
433: anewarray #36; //class java/lang/Object
436: dup
437: iconst_0
438: invokestatic #20; //Method java/lang/System.nanoTime:()J
441: lload 23
443: lsub
444: l2d
445: ldc2_w #37; //double 1.0E-9d
448: dmul
449: invokestatic #44; //Method scala/runtime/BoxesRunTime.boxToDouble:(D)Ljava/lang/Double;
452: aastore
453: invokevirtual #48; //Method scala/Predef$.genericWrapArray:(Ljava/lang/Object;)Lscala/collection/mutable/WrappedArray;
456: astore 25
458: getstatic #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
461: new #3c3c3c; //class scala/collection/immutable/StringOps
464: dup
465: ldc #34; //String Elapsed: %.3f seconds\n
467: invokespecial #424242; //Method scala/collection/immutable/StringOps."":(Ljava/lang/String;)V
470: aload 25
472: invokeinterface #454545, 2; //InterfaceMethod scala/collection/immutable/StringLike.format:(Lscala/collection/Seq;)Ljava/lang/String;
477: invokevirtual #3a3a3a; //Method scala/Console$.print:(Ljava/lang/Object;)V
480: iload 26
482: istore 27
484: getstatic #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
487: new #1e1e1e; //class scala/collection/mutable/StringBuilder
490: dup
491: invokespecial #1f1f1f; //Method scala/collection/mutable/StringBuilder."":()V
494: ldc #484848; //String Checksum =
496: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
499: iload 27
501: invokestatic #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
504: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
507: invokevirtual #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
510: invokevirtual #545454; //Method scala/Predef$.println:(Ljava/lang/Object;)V
513: getstatic #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
516: ldc #4c4c4c; //String Prefix
518: invokevirtual #3a3a3a; //Method scala/Console$.print:(Ljava/lang/Object;)V
521: getstatic #3e3e3e; //Field MODULE$:LTwoMax$;
524: new #525252; //class TwoMax$$anonfun$main$1$$anonfun$2
527: dup
528: aload 29
530: invokespecial #4f4f4f; //Method TwoMax$$anonfun$main$1$$anonfun$2."":(LTwoMax$$anonfun$main$1;)V
533: invokevirtual #595959; //Method ptime:(Lscala/Function0;)Ljava/lang/Object;
536: invokestatic #606060; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
539: istore 28
541: getstatic #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
544: new #1e1e1e; //class scala/collection/mutable/StringBuilder
547: dup
548: invokespecial #1f1f1f; //Method scala/collection/mutable/StringBuilder."":()V
551: ldc #484848; //String Checksum =
553: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
556: iload 28
558: invokestatic #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
561: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
564: invokevirtual #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
567: invokevirtual #545454; //Method scala/Predef$.println:(Ljava/lang/Object;)V
570: getstatic #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
573: ldc #585858; //String If
575: invokevirtual #4e4e4e; //Method scala/Predef$.print:(Ljava/lang/Object;)V
578: getstatic #3e3e3e; //Field MODULE$:LTwoMax$;
581: new #5c5c5c; //class TwoMax$$anonfun$main$1$$anonfun$3
584: dup
585: aload 29
587: invokespecial #555555; //Method TwoMax$$anonfun$main$1$$anonfun$3."":(LTwoMax$$anonfun$main$1;)V
590: invokevirtual #595959; //Method ptime:(Lscala/Function0;)Ljava/lang/Object;
593: invokestatic #606060; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
596: istore 30
598: getstatic #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
601: new #1e1e1e; //class scala/collection/mutable/StringBuilder
604: dup
605: invokespecial #1f1f1f; //Method scala/collection/mutable/StringBuilder."":()V
608: ldc #484848; //String Checksum =
610: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
613: iload 30
615: invokestatic #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
618: invokevirtual #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
621: invokevirtual #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
624: invokevirtual #545454; //Method scala/Predef$.println:(Ljava/lang/Object;)V
627: getstatic #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
630: invokevirtual #646464; //Method scala/Console$.println:()V
633: iload 32
635: aload 31
637: invokevirtual #616161; //Method scala/collection/immutable/Range.step:()I
640: iadd
641: istore 32
643: goto 55

Iulian Dragos
Joined: 2008-12-18,
User offline. Last seen 42 years 45 weeks ago.
Re: math.max(a, b, c)


On Mon, Jan 10, 2011 at 10:11 AM, Paul Phillips <paulp@improving.org> wrote:
On Mon, Jan 10, 2011 at 09:23:19AM +0100, martin odersky wrote:
> Are these the numbers with -optimize on?

Looking at the bytecode, it won't make any difference.

Even if 'max' was inlined, it wouldn't make any difference. Short methods like that are already inlined by the JVM. What would certainly help is scalar replacement, but for the moment we do not have escape analysis. I believe the optimizer would improve a lot if we had it. I know Jesper Norderberg was working on something based on ASM, so maybe you could give that a try.  
 The only
nontrivial difference I see anywhere with and without -optimise is it
going nuts inlining ranges into the main method.  Which, tangentially,
seems of uncertain utility.  In the past I've found that sort of
inlining slower if anything.

Any static optimization may mis-fire. Micro-benchmarks as well. I can say that in many cases inlining ranges improves execution times. It would be great to make ranges even better (there is a lot of residual code that can't be eliminated now), but unfortunately there is not enough man power to handle all things we have to do. I'd be happy to help, but I cannot commit to do it myself any time soon. 
Tangentially, anybody is welcome to help.
cheers,iulian 

// regular style
public void main(java.lang.String[]);
 Code:
  Stack=3, Locals=2, Args_size=2
  0:   getstatic       #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
  3:   iconst_1
  4:   invokevirtual   #69; //Method scala/Predef$.intWrapper:(I)Lscala/runtime/RichInt;
  7:   iconst_3
  8:   invokevirtual   #95; //Method scala/runtime/RichInt.to:(I)Lscala/collection/immutable/Range$Inclusive;
  11:  new     #97; //class TwoMax$$anonfun$main$1
  14:  dup
  15:  invokespecial   #98; //Method TwoMax$$anonfun$main$1."<init>":()V
  18:  invokevirtual   #ccc; //Method scala/collection/immutable/Range$Inclusive.foreach:(Lscala/Function1;)V
  21:  return

// optimiZed style
public void main(java.lang.String[]);
 Code:
  Stack=10, Locals=33, Args_size=2
  0:   new     #71; //class scala/runtime/RichInt
  3:   dup
  4:   iconst_1
  5:   invokespecial   #94; //Method scala/runtime/RichInt."<init>":(I)V
  8:   invokevirtual   #97; //Method scala/runtime/RichInt.self:()I
  11:  istore_3
  12:  new     #99; //class scala/collection/immutable/Range$Inclusive
  15:  dup
  16:  iload_3
  17:  iconst_3
  18:  iconst_1
  19:  invokespecial   #888; //Method scala/collection/immutable/Range$Inclusive."<init>":(III)V
  22:  new     #ccc; //class TwoMax$$anonfun$main$1
  25:  dup
  26:  invokespecial   #eee; //Method TwoMax$$anonfun$main$1."<init>":()V
  29:  astore  29
  31:  dup
  32:  astore  31
  34:  invokevirtual   #fff; //Method scala/collection/immutable/Range.length:()I
  37:  iconst_0
  38:  if_icmple       370
  41:  aload   31
  43:  invokevirtual   #141414; //Method scala/collection/immutable/Range.last:()I
  46:  istore  4
  48:  aload   31
  50:  invokevirtual   #1a1a1a; //Method scala/collection/immutable/Range.start:()I
  53:  istore  32
  55:  iload   32
  57:  iload   4
  59:  if_icmpne       371
  62:  iload   32
  64:  istore  6
  66:  new     #1e1e1e; //class scala/collection/mutable/StringBuilder
  69:  dup
  70:  invokespecial   #1f1f1f; //Method scala/collection/mutable/StringBuilder."<init>":()V
  73:  ldc     #1b1b1b; //String Iteration
  75:  invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  78:  iload   6
  80:  invokestatic    #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
  83:  invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  86:  invokevirtual   #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
  89:  astore  7
  91:  getstatic       #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
  94:  aload   7
  96:  invokevirtual   #303030; //Method scala/Console$.println:(Ljava/lang/Object;)V
  99:  getstatic       #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
  102: ldc     #343434; //String Infix
  104: invokevirtual   #3a3a3a; //Method scala/Console$.print:(Ljava/lang/Object;)V
  107: invokestatic    #20; //Method java/lang/System.nanoTime:()J
  110: lstore  8
  112: getstatic       #3e3e3e; //Field MODULE$:LTwoMax$;
  115: invokevirtual   #393939; //Method testInfix:()I
  118: istore  11
  120: getstatic       #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
  123: iconst_1
  124: anewarray       #36; //class java/lang/Object
  127: dup
  128: iconst_0
  129: invokestatic    #20; //Method java/lang/System.nanoTime:()J
  132: lload   8
  134: lsub
  135: l2d
  136: ldc2_w  #37; //double 1.0E-9d
  139: dmul
  140: invokestatic    #44; //Method scala/runtime/BoxesRunTime.boxToDouble:(D)Ljava/lang/Double;
  143: aastore
  144: invokevirtual   #48; //Method scala/Predef$.genericWrapArray:(Ljava/lang/Object;)Lscala/collection/mutable/WrappedArray;
  147: astore  10
  149: getstatic       #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
  152: new     #3c3c3c; //class scala/collection/immutable/StringOps
  155: dup
  156: ldc     #34; //String Elapsed: %.3f seconds\n
  158: invokespecial   #424242; //Method scala/collection/immutable/StringOps."<init>":(Ljava/lang/String;)V
  161: aload   10
  163: invokeinterface #454545,  2; //InterfaceMethod scala/collection/immutable/StringLike.format:(Lscala/collection/Seq;)Ljava/lang/String;
  168: invokevirtual   #3a3a3a; //Method scala/Console$.print:(Ljava/lang/Object;)V
  171: iload   11
  173: istore  12
  175: new     #1e1e1e; //class scala/collection/mutable/StringBuilder
  178: dup
  179: invokespecial   #1f1f1f; //Method scala/collection/mutable/StringBuilder."<init>":()V
  182: ldc     #484848; //String   Checksum =
  184: invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  187: iload   12
  189: invokestatic    #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
  192: invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  195: invokevirtual   #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
  198: astore  13
  200: getstatic       #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
  203: aload   13
  205: invokevirtual   #303030; //Method scala/Console$.println:(Ljava/lang/Object;)V
  208: getstatic       #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
  211: ldc     #4c4c4c; //String Prefix
  213: invokevirtual   #4e4e4e; //Method scala/Predef$.print:(Ljava/lang/Object;)V
  216: new     #525252; //class TwoMax$$anonfun$main$1$$anonfun$2
  219: dup
  220: aload   29
  222: invokespecial   #4f4f4f; //Method TwoMax$$anonfun$main$1$$anonfun$2."<init>":(LTwoMax$$anonfun$main$1;)V
  225: astore  14
  227: invokestatic    #20; //Method java/lang/System.nanoTime:()J
  230: lstore  15
  232: aload   14
  234: invokevirtual   #525252; //Method TwoMax$$anonfun$main$1$$anonfun$2.apply:()I
  237: istore  17
  239: getstatic       #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
  242: ldc     #34; //String Elapsed: %.3f seconds\n
  244: getstatic       #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
  247: iconst_1
  248: anewarray       #36; //class java/lang/Object
  251: dup
  252: iconst_0
  253: invokestatic    #20; //Method java/lang/System.nanoTime:()J
  256: lload   15
  258: lsub
  259: l2d
  260: ldc2_w  #37; //double 1.0E-9d
  263: dmul
  264: invokestatic    #44; //Method scala/runtime/BoxesRunTime.boxToDouble:(D)Ljava/lang/Double;
  267: aastore
  268: invokevirtual   #48; //Method scala/Predef$.genericWrapArray:(Ljava/lang/Object;)Lscala/collection/mutable/WrappedArray;
  271: invokevirtual   #52; //Method scala/Predef$.printf:(Ljava/lang/String;Lscala/collection/Seq;)V
  274: iload   17
  276: istore  18
  278: getstatic       #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
  281: new     #1e1e1e; //class scala/collection/mutable/StringBuilder
  284: dup
  285: invokespecial   #1f1f1f; //Method scala/collection/mutable/StringBuilder."<init>":()V
  288: ldc     #484848; //String   Checksum =
  290: invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  293: iload   18
  295: invokestatic    #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
  298: invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  301: invokevirtual   #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
  304: invokevirtual   #545454; //Method scala/Predef$.println:(Ljava/lang/Object;)V
  307: getstatic       #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
  310: ldc     #585858; //String If
  312: invokevirtual   #4e4e4e; //Method scala/Predef$.print:(Ljava/lang/Object;)V
  315: getstatic       #3e3e3e; //Field MODULE$:LTwoMax$;
  318: new     #5c5c5c; //class TwoMax$$anonfun$main$1$$anonfun$3
  321: dup
  322: aload   29
  324: invokespecial   #555555; //Method TwoMax$$anonfun$main$1$$anonfun$3."<init>":(LTwoMax$$anonfun$main$1;)V
  327: invokevirtual   #595959; //Method ptime:(Lscala/Function0;)Ljava/lang/Object;
  330: invokestatic    #606060; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
  333: istore  19
  335: getstatic       #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
  338: new     #1e1e1e; //class scala/collection/mutable/StringBuilder
  341: dup
  342: invokespecial   #1f1f1f; //Method scala/collection/mutable/StringBuilder."<init>":()V
  345: ldc     #484848; //String   Checksum =
  347: invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  350: iload   19
  352: invokestatic    #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
  355: invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  358: invokevirtual   #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
  361: invokevirtual   #545454; //Method scala/Predef$.println:(Ljava/lang/Object;)V
  364: getstatic       #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
  367: invokevirtual   #646464; //Method scala/Console$.println:()V
  370: return
  371: iload   32
  373: istore  21
  375: new     #1e1e1e; //class scala/collection/mutable/StringBuilder
  378: dup
  379: invokespecial   #1f1f1f; //Method scala/collection/mutable/StringBuilder."<init>":()V
  382: ldc     #1b1b1b; //String Iteration
  384: invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  387: iload   21
  389: invokestatic    #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
  392: invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  395: invokevirtual   #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
  398: astore  22
  400: getstatic       #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
  403: aload   22
  405: invokevirtual   #303030; //Method scala/Console$.println:(Ljava/lang/Object;)V
  408: getstatic       #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
  411: ldc     #343434; //String Infix
  413: invokevirtual   #3a3a3a; //Method scala/Console$.print:(Ljava/lang/Object;)V
  416: invokestatic    #20; //Method java/lang/System.nanoTime:()J
  419: lstore  23
  421: getstatic       #3e3e3e; //Field MODULE$:LTwoMax$;
  424: invokevirtual   #393939; //Method testInfix:()I
  427: istore  26
  429: getstatic       #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
  432: iconst_1
  433: anewarray       #36; //class java/lang/Object
  436: dup
  437: iconst_0
  438: invokestatic    #20; //Method java/lang/System.nanoTime:()J
  441: lload   23
  443: lsub
  444: l2d
  445: ldc2_w  #37; //double 1.0E-9d
  448: dmul
  449: invokestatic    #44; //Method scala/runtime/BoxesRunTime.boxToDouble:(D)Ljava/lang/Double;
  452: aastore
  453: invokevirtual   #48; //Method scala/Predef$.genericWrapArray:(Ljava/lang/Object;)Lscala/collection/mutable/WrappedArray;
  456: astore  25
  458: getstatic       #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
  461: new     #3c3c3c; //class scala/collection/immutable/StringOps
  464: dup
  465: ldc     #34; //String Elapsed: %.3f seconds\n
  467: invokespecial   #424242; //Method scala/collection/immutable/StringOps."<init>":(Ljava/lang/String;)V
  470: aload   25
  472: invokeinterface #454545,  2; //InterfaceMethod scala/collection/immutable/StringLike.format:(Lscala/collection/Seq;)Ljava/lang/String;
  477: invokevirtual   #3a3a3a; //Method scala/Console$.print:(Ljava/lang/Object;)V
  480: iload   26
  482: istore  27
  484: getstatic       #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
  487: new     #1e1e1e; //class scala/collection/mutable/StringBuilder
  490: dup
  491: invokespecial   #1f1f1f; //Method scala/collection/mutable/StringBuilder."<init>":()V
  494: ldc     #484848; //String   Checksum =
  496: invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  499: iload   27
  501: invokestatic    #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
  504: invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  507: invokevirtual   #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
  510: invokevirtual   #545454; //Method scala/Predef$.println:(Ljava/lang/Object;)V
  513: getstatic       #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
  516: ldc     #4c4c4c; //String Prefix
  518: invokevirtual   #3a3a3a; //Method scala/Console$.print:(Ljava/lang/Object;)V
  521: getstatic       #3e3e3e; //Field MODULE$:LTwoMax$;
  524: new     #525252; //class TwoMax$$anonfun$main$1$$anonfun$2
  527: dup
  528: aload   29
  530: invokespecial   #4f4f4f; //Method TwoMax$$anonfun$main$1$$anonfun$2."<init>":(LTwoMax$$anonfun$main$1;)V
  533: invokevirtual   #595959; //Method ptime:(Lscala/Function0;)Ljava/lang/Object;
  536: invokestatic    #606060; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
  539: istore  28
  541: getstatic       #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
  544: new     #1e1e1e; //class scala/collection/mutable/StringBuilder
  547: dup
  548: invokespecial   #1f1f1f; //Method scala/collection/mutable/StringBuilder."<init>":()V
  551: ldc     #484848; //String   Checksum =
  553: invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  556: iload   28
  558: invokestatic    #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
  561: invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  564: invokevirtual   #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
  567: invokevirtual   #545454; //Method scala/Predef$.println:(Ljava/lang/Object;)V
  570: getstatic       #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
  573: ldc     #585858; //String If
  575: invokevirtual   #4e4e4e; //Method scala/Predef$.print:(Ljava/lang/Object;)V
  578: getstatic       #3e3e3e; //Field MODULE$:LTwoMax$;
  581: new     #5c5c5c; //class TwoMax$$anonfun$main$1$$anonfun$3
  584: dup
  585: aload   29
  587: invokespecial   #555555; //Method TwoMax$$anonfun$main$1$$anonfun$3."<init>":(LTwoMax$$anonfun$main$1;)V
  590: invokevirtual   #595959; //Method ptime:(Lscala/Function0;)Ljava/lang/Object;
  593: invokestatic    #606060; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
  596: istore  30
  598: getstatic       #32; //Field scala/Predef$.MODULE$:Lscala/Predef$;
  601: new     #1e1e1e; //class scala/collection/mutable/StringBuilder
  604: dup
  605: invokespecial   #1f1f1f; //Method scala/collection/mutable/StringBuilder."<init>":()V
  608: ldc     #484848; //String   Checksum =
  610: invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  613: iload   30
  615: invokestatic    #292929; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
  618: invokevirtual   #222222; //Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  621: invokevirtual   #282828; //Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
  624: invokevirtual   #545454; //Method scala/Predef$.println:(Ljava/lang/Object;)V
  627: getstatic       #323232; //Field scala/Console$.MODULE$:Lscala/Console$;
  630: invokevirtual   #646464; //Method scala/Console$.println:()V
  633: iload   32
  635: aload   31
  637: invokevirtual   #616161; //Method scala/collection/immutable/Range.step:()I
  640: iadd
  641: istore  32
  643: goto    55

--
Paul Phillips      | Atheists dig the best foxholes.
Protagonist        |
Empiricist         |
up hill, pi pals!  |----------* http://www.improving.org/paulp/ *----------



--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: math.max(a, b, c)

On Mon, Jan 10, 2011 at 10:53:21AM +0100, iulian dragos wrote:
> Even if 'max' was inlined, it wouldn't make any difference.

I didn't mean to suggest it would. Martin asked if the benchmarks were
run with -optimise, which weakly implies he thought it would make a
difference: so I observed that based on what I saw it generating, it
wasn't going to matter.

> Tangentially, anybody is welcome to help.

Still typing as fast as I can over here.

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: math.max(a, b, c)
On Mon, Jan 10, 2011 at 3:23 AM, martin odersky <martin.odersky@epfl.ch> wrote:


On Sun, Jan 9, 2011 at 8:29 PM, Rex Kerr <ichoran@gmail.com> wrote:
Rich max is not free, even with escape analysis:

java -XX:+DoEscapeAnalysis -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 1.612 seconds
  Checksum = 661242756
Prefix Elapsed: 0.929 seconds
  Checksum = 661242756
If Elapsed: 0.929 seconds
  Checksum = 661242756

java -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 4.574 seconds
  Checksum = 661242756
Prefix Elapsed: 0.922 seconds
  Checksum = 661242756
If Elapsed: 0.922 seconds
  Checksum = 661242756

Infix is (i max j), prefix is math.max(i,j), and if is (if (i<j) j else i).  (Code attached.)

Are these the numbers with -optimize on?

I forget whether I posted the numbers with or without -optimise (with, I think), but I certainly tried both and it didn't make any difference.

  --Rex

H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: math.max(a, b, c)
i tried both on a java 7 vm, no difference

Am 10.01.2011 13:12, schrieb Rex Kerr:
AANLkTimcE1W2GMZ7bB8zy3POi4PSjxNSJvR3bcHCu90c [at] mail [dot] gmail [dot] com" type="cite"> On Mon, Jan 10, 2011 at 3:23 AM, martin odersky <martin [dot] odersky [at] epfl [dot] ch" rel="nofollow">martin.odersky@epfl.ch> wrote:


On Sun, Jan 9, 2011 at 8:29 PM, Rex Kerr <ichoran [at] gmail [dot] com" target="_blank" rel="nofollow">ichoran@gmail.com> wrote:
Rich max is not free, even with escape analysis:

java -XX:+DoEscapeAnalysis -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 1.612 seconds
  Checksum = 661242756
Prefix Elapsed: 0.929 seconds
  Checksum = 661242756
If Elapsed: 0.929 seconds
  Checksum = 661242756

java -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 4.574 seconds
  Checksum = 661242756
Prefix Elapsed: 0.922 seconds
  Checksum = 661242756
If Elapsed: 0.922 seconds
  Checksum = 661242756

Infix is (i max j), prefix is math.max(i,j), and if is (if (i<j) j else i).  (Code attached.)

Are these the numbers with -optimize on?

I forget whether I posted the numbers with or without -optimise (with, I think), but I certainly tried both and it didn't make any difference.

  --Rex


nilskp
Joined: 2009-01-30,
User offline. Last seen 1 year 27 weeks ago.
Re: math.max(a, b, c)
On Sun, Jan 9, 2011 at 12:00 PM, HamsterofDeath <h-star@gmx.de> wrote:
afaik the vm should be able to optimize the allocation away (escape analysis). but i never tested it.

I'm answering this having also read all the following posts. I really don't think escape analysis should matter. One can't make a statement about efficiency with only one JVM implementation in mind, and I don't think scalar replacement was what Martin was thinking of.
H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: math.max(a, b, c)
is there another jvm besides the one from suracle? apache harmony isn't released yet.

Am 10.01.2011 13:52, schrieb Nils Kilden-Pedersen:
SDZ4kxuF [at] mail [dot] gmail [dot] com" type="cite"> On Sun, Jan 9, 2011 at 12:00 PM, HamsterofDeath <h-star [at] gmx [dot] de" rel="nofollow">h-star@gmx.de> wrote:
afaik the vm should be able to optimize the allocation away (escape analysis). but i never tested it.

I'm answering this having also read all the following posts. I really don't think escape analysis should matter. One can't make a statement about efficiency with only one JVM implementation in mind, and I don't think scalar replacement was what Martin was thinking of.

Erik Engbrecht
Joined: 2008-12-19,
User offline. Last seen 3 years 18 weeks ago.
Re: math.max(a, b, c)
Oracle has two, HotSpot from Sun and JRockit from Bea, although they intend to merge them into one.  IBM has a JVM.  Azul Systems has one that is optimized for their machines.  I think there's a host of others that are optimized for specialized uses (e.g. realtime) or specialized hardware.
There's also Android, which while not a JVM is still a path for executing Java bytecode, which does not apply the same optimizations has HotSpot.

On Mon, Jan 10, 2011 at 8:12 AM, HamsterofDeath <h-star@gmx.de> wrote:
is there another jvm besides the one from suracle? apache harmony isn't released yet.

Am 10.01.2011 13:52, schrieb Nils Kilden-Pedersen:
On Sun, Jan 9, 2011 at 12:00 PM, HamsterofDeath <h-star@gmx.de> wrote:
afaik the vm should be able to optimize the allocation away (escape analysis). but i never tested it.

I'm answering this having also read all the following posts. I really don't think escape analysis should matter. One can't make a statement about efficiency with only one JVM implementation in mind, and I don't think scalar replacement was what Martin was thinking of.


Iulian Dragos
Joined: 2008-12-18,
User offline. Last seen 42 years 45 weeks ago.
Re: math.max(a, b, c)


On Mon, Jan 10, 2011 at 11:12 AM, Paul Phillips <paulp@improving.org> wrote:
On Mon, Jan 10, 2011 at 10:53:21AM +0100, iulian dragos wrote:
> Even if 'max' was inlined, it wouldn't make any difference.

I didn't mean to suggest it would.  Martin asked if the benchmarks were
run with -optimise, which weakly implies he thought it would make a
difference: so I observed that based on what I saw it generating, it
wasn't going to matter.

> Tangentially, anybody is welcome to help.

Still typing as fast as I can over here.

I'm sorry if this sounded rude, I literally welcome help from anybody who has the time and passion to work on these things. I know how hard you're working and your contributions to Scala are uncountable.
iulian

 

--
Paul Phillips      | Eschew mastication.
Imperfectionist    |
Empiricist         |
up hill, pi pals!  |----------* http://www.improving.org/paulp/ *----------



--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais
ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: math.max(a, b, c)
The JRockit JVM has weird results.  It elides object creation, but can't optimize while loops properly.  Thus, there is no performance penalty for using the object version.  (I've cut out the _huge_ penalty on the first iteration before it got around to doing the JIT compilation.)

jrmc-4.0.1-1.6.0/bin/java -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 1.255 seconds
  Checksum = 661242756
Prefix Elapsed: 1.398 seconds
  Checksum = 661242756
If Elapsed: 1.471 seconds
  Checksum = 661242756

Hopefully the combined best-of-breed JVM from Oracle will have only the ~30-40% penalty for the object creation case (infix) instead of the 2x penalty presently (and will do so without adopting the JRockit penalty).

  --Rex


On Mon, Jan 10, 2011 at 8:38 AM, Erik Engbrecht <erik.engbrecht@gmail.com> wrote:
Oracle has two, HotSpot from Sun and JRockit from Bea, although they intend to merge them into one.  IBM has a JVM.  Azul Systems has one that is optimized for their machines.  I think there's a host of others that are optimized for specialized uses (e.g. realtime) or specialized hardware.
There's also Android, which while not a JVM is still a path for executing Java bytecode, which does not apply the same optimizations has HotSpot.

On Mon, Jan 10, 2011 at 8:12 AM, HamsterofDeath <h-star@gmx.de> wrote:
is there another jvm besides the one from suracle? apache harmony isn't released yet.

Am 10.01.2011 13:52, schrieb Nils Kilden-Pedersen:
On Sun, Jan 9, 2011 at 12:00 PM, HamsterofDeath <h-star@gmx.de> wrote:
afaik the vm should be able to optimize the allocation away (escape analysis). but i never tested it.

I'm answering this having also read all the following posts. I really don't think escape analysis should matter. One can't make a statement about efficiency with only one JVM implementation in mind, and I don't think scalar replacement was what Martin was thinking of.



H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: math.max(a, b, c)
what about the newest java7-builds? is it still a hotspot-vm, or did they already begin with the merge?

Am 10.01.2011 15:02, schrieb Rex Kerr:
nOPow-ZBs5ngwTq-TVEYLGH5D+Ty [at] mail [dot] gmail [dot] com" type="cite">The JRockit JVM has weird results.  It elides object creation, but can't optimize while loops properly.  Thus, there is no performance penalty for using the object version.  (I've cut out the _huge_ penalty on the first iteration before it got around to doing the JIT compilation.)

jrmc-4.0.1-1.6.0/bin/java -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 1.255 seconds
  Checksum = 661242756
Prefix Elapsed: 1.398 seconds
  Checksum = 661242756
If Elapsed: 1.471 seconds
  Checksum = 661242756

Hopefully the combined best-of-breed JVM from Oracle will have only the ~30-40% penalty for the object creation case (infix) instead of the 2x penalty presently (and will do so without adopting the JRockit penalty).

  --Rex


On Mon, Jan 10, 2011 at 8:38 AM, Erik Engbrecht <erik [dot] engbrecht [at] gmail [dot] com" rel="nofollow">erik.engbrecht@gmail.com> wrote:
Oracle has two, HotSpot from Sun and JRockit from Bea, although they intend to merge them into one.  IBM has a JVM.  Azul Systems has one that is optimized for their machines.  I think there's a host of others that are optimized for specialized uses (e.g. realtime) or specialized hardware.
There's also Android, which while not a JVM is still a path for executing Java bytecode, which does not apply the same optimizations has HotSpot.

On Mon, Jan 10, 2011 at 8:12 AM, HamsterofDeath <h-star [at] gmx [dot] de" target="_blank" rel="nofollow">h-star@gmx.de> wrote:
is there another jvm besides the one from suracle? apache harmony isn't released yet.

Am 10.01.2011 13:52, schrieb Nils Kilden-Pedersen:
On Sun, Jan 9, 2011 at 12:00 PM, HamsterofDeath <h-star [at] gmx [dot] de" target="_blank" rel="nofollow">h-star@gmx.de> wrote:
afaik the vm should be able to optimize the allocation away (escape analysis). but i never tested it.

I'm answering this having also read all the following posts. I really don't think escape analysis should matter. One can't make a statement about efficiency with only one JVM implementation in mind, and I don't think scalar replacement was what Martin was thinking of.




Alec Zorab
Joined: 2010-05-18,
User offline. Last seen 42 years 45 weeks ago.
Re: math.max(a, b, c)

In a minor digression from the actual theme of the thread, has anyone
played with the Azul Systems' zing jvm with scala? Having read a
couple of the white papers it looks like it should be pretty decent,
but I haven't gotten around to getting an evaluation license for it
yet.

On Mon, Jan 10, 2011 at 2:21 PM, HamsterofDeath wrote:
> what about the newest java7-builds? is it still a hotspot-vm, or did they
> already begin with the merge?
>
> Am 10.01.2011 15:02, schrieb Rex Kerr:
>
> The JRockit JVM has weird results.  It elides object creation, but can't
> optimize while loops properly.  Thus, there is no performance penalty for
> using the object version.  (I've cut out the _huge_ penalty on the first
> iteration before it got around to doing the JIT compilation.)
>
> jrmc-4.0.1-1.6.0/bin/java -cp /usr/share/scala/2.8/lib/scala-library.jar:.
> TwoMax
> //(warmup elided)
> Iteration 3
> Infix Elapsed: 1.255 seconds
>   Checksum = 661242756
> Prefix Elapsed: 1.398 seconds
>   Checksum = 661242756
> If Elapsed: 1.471 seconds
>   Checksum = 661242756
>
> Hopefully the combined best-of-breed JVM from Oracle will have only the
> ~30-40% penalty for the object creation case (infix) instead of the 2x
> penalty presently (and will do so without adopting the JRockit penalty).
>
>   --Rex
>
>
> On Mon, Jan 10, 2011 at 8:38 AM, Erik Engbrecht
> wrote:
>>
>> Oracle has two, HotSpot from Sun and JRockit from Bea, although they
>> intend to merge them into one.  IBM has a JVM.  Azul Systems has one that is
>> optimized for their machines.  I think there's a host of others that are
>> optimized for specialized uses (e.g. realtime) or specialized hardware.
>> There's also Android, which while not a JVM is still a path for executing
>> Java bytecode, which does not apply the same optimizations has HotSpot.
>>
>> On Mon, Jan 10, 2011 at 8:12 AM, HamsterofDeath wrote:
>>>
>>> is there another jvm besides the one from suracle? apache harmony isn't
>>> released yet.
>>>
>>> Am 10.01.2011 13:52, schrieb Nils Kilden-Pedersen:
>>>
>>> On Sun, Jan 9, 2011 at 12:00 PM, HamsterofDeath wrote:
>>>>
>>>> afaik the vm should be able to optimize the allocation away (escape
>>>> analysis). but i never tested it.
>>>
>>> I'm answering this having also read all the following posts. I really
>>> don't think escape analysis should matter. One can't make a statement about
>>> efficiency with only one JVM implementation in mind, and I don't think
>>> scalar replacement was what Martin was thinking of.
>>>
>>
>
>
>

Aydjen
Joined: 2009-08-21,
User offline. Last seen 1 year 28 weeks ago.
Re: math.max(a, b, c)

Hi again,

just in case anyone cares, on Apple's 64-bit VM, I get the following results when using long arithmetic (http://paste.pocoo.org/show/318160/):

java -cp /opt/local/share/scala-2.8/lib/scala-library.jar:. TwoMax

Iteration 3
Infix Elapsed: 4,936 seconds
Checksum = 3338615082255021824
Prefix Elapsed: 0,856 seconds
Checksum = 3338615082255021824
If Elapsed: 0,863 seconds
Checksum = 3338615082255021824

java -XX:+DoEscapeAnalysis -cp /opt/local/share/scala-2.8/lib/scala-library.jar:. TwoMax

Iteration 3
Infix Elapsed: 0,858 seconds
Checksum = 3338615082255021824
Prefix Elapsed: 0,865 seconds
Checksum = 3338615082255021824
If Elapsed: 0,863 seconds
Checksum = 3338615082255021824

Looks good to me. No... it impresses me.

The original benchmark, using Ints, yielded the following:

java -cp /opt/local/share/scala-2.8/lib/scala-library.jar:. TwoMax

Iteration 3
Infix Elapsed: 5,097 seconds
Checksum = 661242756
Prefix Elapsed: 0,918 seconds
Checksum = 661242756
If Elapsed: 0,919 seconds
Checksum = 661242756

java -XX:+DoEscapeAnalysis -cp /opt/local/share/scala-2.8/lib/scala-library.jar:. TwoMax

Iteration 3
Infix Elapsed: 1,585 seconds
Checksum = 661242756
Prefix Elapsed: 0,918 seconds
Checksum = 661242756
If Elapsed: 0,920 seconds
Checksum = 661242756

Looks not so good.

Kind regards
Andreas

H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: math.max(a, b, c)

more numbers:

java7, server, 64 bit:
Iteration 1
Infix Elapsed: 0,831 seconds
Checksum = 3338615082255021824
Prefix Elapsed: 0,830 seconds
Checksum = 3338615082255021824
If Elapsed: 0,830 seconds
Checksum = 3338615082255021824

java7, server, 32 bit, surprise:

Iteration 6
Infix Elapsed: 3,246 seconds
Checksum = 3338615082255021824
Prefix Elapsed: 3,222 seconds
Checksum = 3338615082255021824
If Elapsed: 3,239 seconds
Checksum = 3338615082255021824

Am 10.01.2011 16:32, schrieb Andreas Flierl:
> Hi again,
>
> just in case anyone cares, on Apple's 64-bit VM, I get the following results when using long arithmetic (http://paste.pocoo.org/show/318160/):
>
> java -cp /opt/local/share/scala-2.8/lib/scala-library.jar:. TwoMax
>
> Iteration 3
> Infix Elapsed: 4,936 seconds
> Checksum = 3338615082255021824
> Prefix Elapsed: 0,856 seconds
> Checksum = 3338615082255021824
> If Elapsed: 0,863 seconds
> Checksum = 3338615082255021824
>
> java -XX:+DoEscapeAnalysis -cp /opt/local/share/scala-2.8/lib/scala-library.jar:. TwoMax
>
> Iteration 3
> Infix Elapsed: 0,858 seconds
> Checksum = 3338615082255021824
> Prefix Elapsed: 0,865 seconds
> Checksum = 3338615082255021824
> If Elapsed: 0,863 seconds
> Checksum = 3338615082255021824
>
> Looks good to me. No... it impresses me.
>
> The original benchmark, using Ints, yielded the following:
>
> java -cp /opt/local/share/scala-2.8/lib/scala-library.jar:. TwoMax
>
> Iteration 3
> Infix Elapsed: 5,097 seconds
> Checksum = 661242756
> Prefix Elapsed: 0,918 seconds
> Checksum = 661242756
> If Elapsed: 0,919 seconds
> Checksum = 661242756
>
> java -XX:+DoEscapeAnalysis -cp /opt/local/share/scala-2.8/lib/scala-library.jar:. TwoMax
>
> Iteration 3
> Infix Elapsed: 1,585 seconds
> Checksum = 661242756
> Prefix Elapsed: 0,918 seconds
> Checksum = 661242756
> If Elapsed: 0,920 seconds
> Checksum = 661242756
>
> Looks not so good.
>
> Kind regards
> Andreas

Aydjen
Joined: 2009-08-21,
User offline. Last seen 1 year 28 weeks ago.
Re: math.max(a, b, c)

HamsterofDeath wrote:

> more numbers:

So... the question I have is:
Why does this escape analysis work very well with long arithmetic on a 64bit system/VM (no visible overhead) but not nearly as well with int arithmetic on a 32bit system/VM (200% or more overhead)?

Seems to me that something is going very wrong.

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