- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
math.max(a, b, c)
Fri, 2011-01-07, 20:13
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
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
Fri, 2011-01-07, 20:27
#2
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
Fri, 2011-01-07, 20:37
#3
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:
--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
Fri, 2011-01-07, 20:47
#4
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:
--
Daniel C. Sobral
I travel to the future all the time.
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.
Fri, 2011-01-07, 20:57
#5
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
>
>>
>> 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-----
Fri, 2011-01-07, 21:17
#6
Re: math.max(a, b, c)
On Fri, Jan 7, 2011 at 11:19 AM, Daniel Sobral <dcsobral@gmail.com> wrote:
Russ P.
--
http://RussP.us
It is not without consequence: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.
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)
^
Russ P.
--
http://RussP.us
Sun, 2011-01-09, 14:47
#7
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:
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: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.
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)
^
Russ P.
--
http://RussP.us
Sun, 2011-01-09, 14:57
#8
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:
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: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.
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)
^
Russ P.
--
http://RussP.us
Sun, 2011-01-09, 15:27
#9
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: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.
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)
^
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
Sun, 2011-01-09, 15:47
#10
Re: math.max(a, b, c)
give it another name: maxOf(a,b*) :D
Am 09.01.2011 15:18, schrieb Kevin Wright:
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: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.
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)
^
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
Sun, 2011-01-09, 16:17
#11
Re: math.max(a, b, c)
On Sun, Jan 9, 2011 at 8:18 AM, Kevin Wright <kev.lee.wright@gmail.com> wrote:
You mean in general, or for the specific case given?
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?
Sun, 2011-01-09, 16:27
#12
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
Sun, 2011-01-09, 16:37
#13
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
math.max(1, 2, 3)
would be neither shorter nor more legible or more efficient than
1 max 2 max 3
Cheers
-- Martin
Sun, 2011-01-09, 17:47
#14
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
>
Sun, 2011-01-09, 18:37
#15
Re: math.max(a, b, c)
On Sun, Jan 9, 2011 at 9:35 AM, martin odersky <martin.odersky@epfl.ch> wrote:
Doesn't the infix require the construction of a RichInt on every invocation, or is infix max compiler optimized?
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?
Sun, 2011-01-09, 19:07
#16
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:
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?
Sun, 2011-01-09, 20:37
#17
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:
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?
Sun, 2011-01-09, 21:57
#18
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-----
Sun, 2011-01-09, 22:07
#19
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:
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?
Sun, 2011-01-09, 22:37
#20
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:
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.
Sun, 2011-01-09, 23:27
#21
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:
--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?
Mon, 2011-01-10, 00:17
#22
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.
>
>
Mon, 2011-01-10, 09:27
#23
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:Are these the numbers with -optimize on?
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.)
Cheers
-- Martin
Mon, 2011-01-10, 09:37
#24
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...
Mon, 2011-01-10, 09:57
#25
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
Mon, 2011-01-10, 10:17
#26
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
Mon, 2011-01-10, 10:57
#27
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
Mon, 2011-01-10, 11:17
#28
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.
Mon, 2011-01-10, 13:17
#29
Re: math.max(a, b, c)
On Mon, Jan 10, 2011 at 3:23 AM, martin odersky <martin.odersky@epfl.ch> wrote:
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
On Sun, Jan 9, 2011 at 8:29 PM, Rex Kerr <ichoran@gmail.com> wrote:Rich max is not free, even with escape analysis:Are these the numbers with -optimize on?
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.)
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
Mon, 2011-01-10, 13:47
#30
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:
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:Are these the numbers with -optimize on?
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.)
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
Mon, 2011-01-10, 13:57
#31
Re: math.max(a, b, c)
On Sun, Jan 9, 2011 at 12:00 PM, HamsterofDeath <h-star@gmx.de> wrote:
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.
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.
Mon, 2011-01-10, 14:17
#32
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:
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.
Mon, 2011-01-10, 14:47
#33
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:
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.
Mon, 2011-01-10, 15:07
#34
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
Mon, 2011-01-10, 15:17
#35
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:
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.
Mon, 2011-01-10, 15:27
#36
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:
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.
Mon, 2011-01-10, 15:57
#37
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.
>>>
>>
>
>
>
Mon, 2011-01-10, 16:37
#38
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
Mon, 2011-01-10, 21:07
#39
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
Mon, 2011-01-10, 21:27
#40
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.
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