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

r19952: performance degradation

11 replies
anli
Joined: 2008-08-19,
User offline. Last seen 1 day 45 min ago.

Hi!

Unfortunately, I have no an idea how to prepare short and self-contained test
case, so, I'll just describe what I have in hand, and probably somebody
suggest such test.

So, I have two integration tests:

1. Testing http server [1] with ApacheBench. At the same conditions I have got
~6600 requests per second instead of ~8800 rps before r19952.

2. Text-templating. It's a significantly simplified (and String oriented)
parser combinators based on Adriaan's article about Scala parsers. The same
test takes 14-15 seconds with r19952 instead of ~8.4 seconds with earlier
versions.

Of course, results are gathering after warming JVM up. And, of course, many
revisions before and after r19952 were tried - historically and during
bisecting.

Both test cases are too different to guess about degradation reason without
knowing Scala deep internals. httpd, being tuned for performance, resembles,
in fact, assembler - it deals with NIO, sockets, concurrency and so on. The
second test - well, Adriaan has wrote all about it. You see, in a whole the
tests are absolutely different jazz bands.

Enviroment:

$ uname -a
Linux 2.6.31-16-generic #52-Ubuntu SMP Thu Dec 3 22:07:16 UTC 2009 x86_64
GNU/Linux

~$ java -version
java version "1.6.0_15"
Java(TM) SE Runtime Environment (build 1.6.0_15-b03)
Java HotSpot(TM) 64-Bit Server VM (build 14.1-b02, mixed mode)

Regards!
Andrew

[1] http://gaydenko.com/scala/tiscaf/httpd/

ijuma
Joined: 2008-08-20,
User offline. Last seen 22 weeks 2 days ago.
Re: r19952: performance degradation

On Sun, 2009-12-06 at 13:17 +0300, Andrew Gaydenko wrote:
> Of course, results are gathering after warming JVM up. And, of course, many
> revisions before and after r19952 were tried - historically and during
> bisecting.

By the way, r19952 is:

"fix msil code generation for exception handlers."
https://lampsvn.epfl.ch/trac/scala/changeset/19952

When I saw that commit, I thought it just affected the msil back-end.
Does it also change the code emitted by the JVM back-end?

Best,
Ismael

rytz
Joined: 2008-07-01,
User offline. Last seen 45 weeks 5 days ago.
Re: r19952: performance degradation


On Sun, Dec 6, 2009 at 11:26, Ismael Juma <mlists@juma.me.uk> wrote:
On Sun, 2009-12-06 at 13:17 +0300, Andrew Gaydenko wrote:
> Of course, results are gathering after warming JVM up. And, of course, many
> revisions before and after r19952 were tried - historically and during
> bisecting.

By the way, r19952 is:

"fix msil code generation for exception handlers."
https://lampsvn.epfl.ch/trac/scala/changeset/19952

When I saw that commit, I thought it just affected the msil back-end.
Does it also change the code emitted by the JVM back-end?

No, except for one minor change. For a `try`-`catch` with a `finally`, the
exception handler covering the `catch` blocks (which makes sure that the
finalizer gets executed even if an exception is thrown inside a `catch`
handler) now has `Throwable` as type in the exception table, not `null`.

This should not change performance (and of course not the semantics either)
I guess..
anli
Joined: 2008-08-19,
User offline. Last seen 1 day 45 min ago.
Re: r19952: performance degradation

On Sunday 06 December 2009 16:10:54 Lukas Rytz wrote:
> No, except for one minor change. For a `try`-`catch` with a `finally`, the
> exception handler covering the `catch` blocks (which makes sure that the
> finalizer gets executed even if an exception is thrown inside a `catch`
> handler) now has `Throwable` as type in the exception table, not `null`.
>
> This should not change performance (and of course not the semantics either)
> I guess..

Lukas,

Thanks for the hint! Have got it. This code:

//---- code start
object R19952 {

val range = 1 to 20000000
val count = 1 to 20

def step {
val started = new java.util.Date
try { range.foldLeft(0)(_+_) } catch { case _ => }
val delta = (new java.util.Date getTime) - started.getTime
println("delta: " + delta)
}

def main(a : Array[String]) : Unit = {
count.foreach(_ => step)
}

}
//---- code end

being started with this script:

//---- scripy start
#!/bin/bash

ORIG_PATH=$PATH

PATH=/wrk/dev/scala/SVN/dists/r19951/bin:$ORIG_PATH
scala -version
rm *.class
scalac R19952.scala
scala R19952

PATH=/wrk/dev/scala/SVN/dists/r19952/bin:$ORIG_PATH
scala -version
rm *.class
scalac R19952.scala
scala R19952
//---- script end

produces this output:

//---- output start
$ ./start.sh
Scala code runner version 2.8.0.r19951-b20091206092628 -- Copyright 2002-2009,
LAMP/EPFL
delta: 544
delta: 520
delta: 506
delta: 506
delta: 507
delta: 507
delta: 507
delta: 498
delta: 508
delta: 509
delta: 507
delta: 505
delta: 506
delta: 503
delta: 502
delta: 510
delta: 506
delta: 506
delta: 502
delta: 509
Scala code runner version 2.8.0.r19952-b20091206030507 -- Copyright 2002-2009,
LAMP/EPFL
delta: 1182
delta: 1395
delta: 1155
delta: 1340
delta: 1342
delta: 1349
delta: 1336
delta: 1328
delta: 1102
delta: 1331
delta: 1350
delta: 1344
delta: 1344
delta: 1344
delta: 1339
delta: 1345
delta: 1350
delta: 1349
delta: 1345
delta: 1350
//---- output end

Andrew

rytz
Joined: 2008-07-01,
User offline. Last seen 45 weeks 5 days ago.
Re: r19952: performance degradation
Thanks for trimming it down. I'll have a look.

On Sun, Dec 6, 2009 at 14:59, Andrew Gaydenko <a@gaydenko.com> wrote:
On Sunday 06 December 2009 16:10:54 Lukas Rytz wrote:
> No, except for one minor change. For a `try`-`catch` with a `finally`, the
> exception handler covering the `catch` blocks (which makes sure that the
> finalizer gets executed even if an exception is thrown inside a `catch`
> handler) now has `Throwable` as type in the exception table, not `null`.
>
> This should not change performance (and of course not the semantics either)
> I guess..

Lukas,

Thanks for the hint! Have got it. This code:

//---- code start
object R19952 {

 val range = 1 to 20000000
 val count = 1 to 20

 def step {
   val started = new java.util.Date
   try { range.foldLeft(0)(_+_) } catch { case _ => }
   val delta = (new java.util.Date getTime) - started.getTime
   println("delta: " + delta)
 }

 def main(a : Array[String]) : Unit = {
   count.foreach(_ =>  step)
 }

}
//---- code end

being started with this script:

//---- scripy start
#!/bin/bash

ORIG_PATH=$PATH

PATH=/wrk/dev/scala/SVN/dists/r19951/bin:$ORIG_PATH
scala -version
rm *.class
scalac R19952.scala
scala R19952

PATH=/wrk/dev/scala/SVN/dists/r19952/bin:$ORIG_PATH
scala -version
rm *.class
scalac R19952.scala
scala R19952
//---- script end

produces this output:

//---- output start
$ ./start.sh
Scala code runner version 2.8.0.r19951-b20091206092628 -- Copyright 2002-2009,
LAMP/EPFL
delta: 544
delta: 520
delta: 506
delta: 506
delta: 507
delta: 507
delta: 507
delta: 498
delta: 508
delta: 509
delta: 507
delta: 505
delta: 506
delta: 503
delta: 502
delta: 510
delta: 506
delta: 506
delta: 502
delta: 509
Scala code runner version 2.8.0.r19952-b20091206030507 -- Copyright 2002-2009,
LAMP/EPFL
delta: 1182
delta: 1395
delta: 1155
delta: 1340
delta: 1342
delta: 1349
delta: 1336
delta: 1328
delta: 1102
delta: 1331
delta: 1350
delta: 1344
delta: 1344
delta: 1344
delta: 1339
delta: 1345
delta: 1350
delta: 1349
delta: 1345
delta: 1350
//---- output end

Andrew


extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: r19952: performance degradation

On Sun, Dec 06, 2009 at 05:36:20PM +0100, Lukas Rytz wrote:
> Thanks for trimming it down. I'll have a look.

Also, I reproduced the slowdown and verified that this diff alone is
enough to induce it.

- (NoSymbol, expectedType, exhCtx => {
+ (ThrowableClass, expectedType, exhCtx => {

rytz
Joined: 2008-07-01,
User offline. Last seen 45 weeks 5 days ago.
Re: r19952: performance degradation
amazing.. this probably means that we can speed up any exception
handler catching `Throwable`.

On Sun, Dec 6, 2009 at 19:14, Paul Phillips <paulp@improving.org> wrote:
On Sun, Dec 06, 2009 at 05:36:20PM +0100, Lukas Rytz wrote:
> Thanks for trimming it down. I'll have a look.

Also, I reproduced the slowdown and verified that this diff alone is
enough to induce it.

-          (NoSymbol, expectedType, exhCtx => {
+          (ThrowableClass, expectedType, exhCtx => {

--
Paul Phillips      | Where there's smoke, there's mirrors!
Future Perfect     |
Empiricist         |
pal, i pill push   |----------* http://www.improving.org/paulp/ *----------

anli
Joined: 2008-08-19,
User offline. Last seen 1 day 45 min ago.
Re: r19952: performance degradation

On Sunday 06 December 2009 23:51:09 Lukas Rytz wrote:
> amazing.. this probably means that we can speed up any exception
> handler catching `Throwable`.

so, shortly will be better than ever?

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: r19952: performance degradation

On Sun, Dec 06, 2009 at 09:51:09PM +0100, Lukas Rytz wrote:
> amazing.. this probably means that we can speed up any exception
> handler catching `Throwable`.

I was thinking the same thing - this will turn out to be one of those
performance regressions which ends up leading to a win. We would really
benefit from a regression suite which is specifically looking for
performance backsliding; if we didn't have andrew to catch this one
immediately, I expect it might have remained for a long time.

Johannes Rudolph
Joined: 2008-12-17,
User offline. Last seen 29 weeks 20 hours ago.
Re: r19952: performance degradation

Cross-posting to the JVM Languages group. You might want to see the
history of this thread as well:

http://old.nabble.com/-scala--r19952%3A-performance-degradation-to266635...

Can anyone from the experts comment on the fact why using null as
exception type ('any' in javap) in a handler instead of Throwable
results in such a big performance win (> 2x) ? Is it a special
performance optimization in the Hotspot VM for finally clauses? Is it
known and documented somewhere?

Thanks,
Johannes

On Sun, Dec 6, 2009 at 9:51 PM, Lukas Rytz wrote:
> amazing.. this probably means that we can speed up any exception
> handler catching `Throwable`.
>
> On Sun, Dec 6, 2009 at 19:14, Paul Phillips wrote:
>>
>> On Sun, Dec 06, 2009 at 05:36:20PM +0100, Lukas Rytz wrote:
>> > Thanks for trimming it down. I'll have a look.
>>
>> Also, I reproduced the slowdown and verified that this diff alone is
>> enough to induce it.
>>
>> -          (NoSymbol, expectedType, exhCtx => {
>> +          (ThrowableClass, expectedType, exhCtx => {
>>
>> --
>> Paul Phillips      | Where there's smoke, there's mirrors!
>> Future Perfect     |
>> Empiricist         |
>> pal, i pill push   |----------* http://www.improving.org/paulp/
>> *----------
>
>

anli
Joined: 2008-08-19,
User offline. Last seen 1 day 45 min ago.
Re: r19952: performance degradation

On Sunday 06 December 2009 23:51:09 Lukas Rytz wrote:
> amazing.. this probably means that we can speed up any exception
> handler catching `Throwable`.

Have tried the r20050 fix. Results against r19951 are:

- small test published here - approximately the same
- httpd ApacheBench-marking - 15-20%(!) faster
- text-oriented combinators - 5-7% faster

Great, thanks!

Andrew

ijuma
Joined: 2008-08-20,
User offline. Last seen 22 weeks 2 days ago.
Re: r19952: performance degradation

On Tue, 2009-12-08 at 14:40 +0300, Andrew Gaydenko wrote:
> On Sunday 06 December 2009 23:51:09 Lukas Rytz wrote:
> > amazing.. this probably means that we can speed up any exception
> > handler catching `Throwable`.
>
> Have tried the r20050 fix. Results against r19951 are:
>
> - small test published here - approximately the same
> - httpd ApacheBench-marking - 15-20%(!) faster
> - text-oriented combinators - 5-7% faster
>
> Great, thanks!

This should win the "most unexpected source of performance improvement"
award for 2009. Amazing.

Thanks for noticing the change and narrowing it down to a single
revision, Andrew. I don't think this would have been found otherwise.

Best,
Ismael

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