Thread overview
try-catch exception handling speed should be improved!.
May 22, 2004
Lord Syl
May 22, 2004
Ilya Minkov
May 22, 2004
Roel Mathys
May 22, 2004
Lord Syl
May 22, 2004
Norbert Nemec
May 22, 2004
Lord Syl
May 23, 2004
Matthew
May 23, 2004
Walter
May 23, 2004
Phill
May 22, 2004
Hey, I just made a quick test, in order to see method calls' speed.
When I compared the results to Java's, I found interesting that Java (running
via JVM) had beaten D in the Try-Catch exception handling speed area, while
running slow as hell in the rest.

Here are the results:

<[D] 500 Million Calls speed test >>

TryCatched - 13750 ms
!TryCatched - 1933 ms
Directly - 1292 ms

Compiler version is 0.90, with commandline -O -release -inline

<[Java] 500 Million Calls speed test >>

TryCatched - 10926 ms
!TryCatched - 4406 ms
Directly - 4597 ms

Using Java VM v1.50 beta from Sun

Tests were done on a Duron 800(6x133) processor with  640Mb@266Mhz RAM under
Windows XP.

[D source code]

import std.date;
int main (char[][] args)
{
int i, j=-42;
printf(" ##### 500 Million Calls Speed Test #####\n");
long START_TC=getUTCtime();
for (i=0; i<500000000; i++) j=TCcall(i);
long END_TC=getUTCtime();
long START=getUTCtime();
for (i=0; i<500000000; i++) j=Ccall(i);
long END=getUTCtime();
long start=getUTCtime();
for(i=0; i<500000000; i++) j=i+4;
long end=getUTCtime();
printf("(TryCatched) Elapsed (ms) : %d\n",(END_TC-START_TC));
printf("(!TryCatched) Elapsed (ms) : %d\n",(END-START));
printf("(Directly) Elapsed (ms) : %d\n",(end-start));
return 0;
}

static final int TCcall(int I)
{
try
{
I+=4;
return I;
}
catch(Error e) { return I; }
}

static final int Ccall(int I)
{
I+=4;
return I;
}

[Java code]

public class PointlessSpeedTest
{
public static void main (String[] args)
{
int i, j=-42;
System.out.println("##### 500 Million Calls Speed Test #####");
long START_TC=System.currentTimeMillis();
for (i=0; i<500000000; i++) j=TCcall(i);
long END_TC=System.currentTimeMillis();
long START=System.currentTimeMillis();
for (i=0; i<500000000; i++) j=Ccall(i);
long END=System.currentTimeMillis();
long start=System.currentTimeMillis();
for(i=0; i<500000000; i++) j=i+4;
long end=System.currentTimeMillis();
System.out.println("(TryCatched) Elapsed: "+(END_TC-START_TC)+" ms");
System.out.println("(!TryCatched) Elapsed: "+(END-START)+" ms");
System.out.println("(Directly) Elapsed: "+(end-start)+" ms");
}

private static int TCcall(int I)
{
try
{
I+=4;
return I;
}
catch(Exception ex) { return I; }
}

private static int Ccall(int I)
{
I+=4;
return I;
}
}


May 22, 2004
Lord Syl schrieb:

> Hey, I just made a quick test, in order to see method calls' speed.
> When I compared the results to Java's, I found interesting that Java (running
> via JVM) had beaten D in the Try-Catch exception handling speed area, while
> running slow as hell in the rest.

No, speed of try/catch shouldn't be improved. The main guideline for implementation of exception handling is that it should slow down the normal run of the program - i.e. without exceptions being thrown - as little as possible. And your test tells me rather that DigitalMars implementation succeeds in that well. And well, 1/3 difference is not important - exceptions can take even much longer time to process depending on circumstances and should not be used in performance sensitive code. It's a tradeoff which was made wisely.

-eye
May 22, 2004
Ilya Minkov wrote:
> Lord Syl schrieb:
> 
>> Hey, I just made a quick test, in order to see method calls' speed.
>> When I compared the results to Java's, I found interesting that Java (running
>> via JVM) had beaten D in the Try-Catch exception handling speed area, while
>> running slow as hell in the rest.
> 
> 
> No, speed of try/catch shouldn't be improved. The main guideline for implementation of exception handling is that it should slow down the normal run of the program - i.e. without exceptions being thrown - as little as possible. And your test tells me rather that DigitalMars implementation succeeds in that well. And well, 1/3 difference is not important - exceptions can take even much longer time to process depending on circumstances and should not be used in performance sensitive code. It's a tradeoff which was made wisely.
> 
> -eye

I would phrase it like this: performance isn't the prime objective of exception handling, but I don't see an issue in it being optimized performance wise

rm
May 22, 2004
In article <c8ne2r$i2l$1@digitaldaemon.com>, Ilya Minkov says...

>No, speed of try/catch shouldn't be improved. The main guideline for implementation of exception handling is that it should slow down the normal run of the program - i.e. without exceptions being thrown - as little as possible. And your test tells me rather that DigitalMars implementation succeeds in that well. And well, 1/3 difference is not important - exceptions can take even much longer time to process depending on circumstances and should not be used in performance sensitive code. It's a tradeoff which was made wisely.
>
>-eye

You didn't take into account that, although the "absolute" difference is a 30%, the other results were there for something.

According to those results, the (exception handled)/(non-exception handled)
proportion in Java is around 250%, while D shows there a 700%, so some
improvement is possible there.
At all, one of the points of exception handling is to avoid the need to use
"defensive code" to improve readability and increase performance.


May 22, 2004
Ilya Minkov wrote:

> Lord Syl schrieb:
> 
>> Hey, I just made a quick test, in order to see method calls' speed. When I compared the results to Java's, I found interesting that Java (running via JVM) had beaten D in the Try-Catch exception handling speed area, while running slow as hell in the rest.
> 
> No, speed of try/catch shouldn't be improved. The main guideline for implementation of exception handling is that it should slow down the normal run of the program - i.e. without exceptions being thrown - as little as possible. And your test tells me rather that DigitalMars implementation succeeds in that well.

Sure? If I understand the code correctly, it measures the time of the try/catch block *without throwing exceptions*, which would mean, that the DM compiler really does not follow your "main guideline". Of course "throw" need not be optimized for speed, but try/catch should not cost that much!

May 22, 2004
In article <c8nnp6$uil$3@digitaldaemon.com>, Norbert Nemec says...
>

>Sure? If I understand the code correctly, it measures the time of the try/catch block *without throwing exceptions*, which would mean, that the DM compiler really does not follow your "main guideline". Of course "throw" need not be optimized for speed, but try/catch should not cost that much!
>

You got it :) . The code measures the setup time, as it's important, specially for system apps, that if a set of methods which are called continuously are written using exception handling, if there is no error on the data they receive (no exception is caused) then it isn't slowed down too much.


May 23, 2004
AFAIK, D's exceptions are layered on top of the Win32 SEH, whereas Java does not.

Check out http://www.windevnet.com/wdn/webextra/2003/0313/


"Lord Syl" <Lord_member@pathlink.com> wrote in message news:c8ncf8$g3r$1@digitaldaemon.com...
> Hey, I just made a quick test, in order to see method calls' speed.
> When I compared the results to Java's, I found interesting that Java (running
> via JVM) had beaten D in the Try-Catch exception handling speed area, while
> running slow as hell in the rest.
>
> Here are the results:
>
> <[D] 500 Million Calls speed test >>
>
> TryCatched - 13750 ms
> !TryCatched - 1933 ms
> Directly - 1292 ms
>
> Compiler version is 0.90, with commandline -O -release -inline
>
> <[Java] 500 Million Calls speed test >>
>
> TryCatched - 10926 ms
> !TryCatched - 4406 ms
> Directly - 4597 ms
>
> Using Java VM v1.50 beta from Sun
>
> Tests were done on a Duron 800(6x133) processor with  640Mb@266Mhz RAM under
> Windows XP.
>
> [D source code]
>
> import std.date;
> int main (char[][] args)
> {
> int i, j=-42;
> printf(" ##### 500 Million Calls Speed Test #####\n");
> long START_TC=getUTCtime();
> for (i=0; i<500000000; i++) j=TCcall(i);
> long END_TC=getUTCtime();
> long START=getUTCtime();
> for (i=0; i<500000000; i++) j=Ccall(i);
> long END=getUTCtime();
> long start=getUTCtime();
> for(i=0; i<500000000; i++) j=i+4;
> long end=getUTCtime();
> printf("(TryCatched) Elapsed (ms) : %d\n",(END_TC-START_TC));
> printf("(!TryCatched) Elapsed (ms) : %d\n",(END-START));
> printf("(Directly) Elapsed (ms) : %d\n",(end-start));
> return 0;
> }
>
> static final int TCcall(int I)
> {
> try
> {
> I+=4;
> return I;
> }
> catch(Error e) { return I; }
> }
>
> static final int Ccall(int I)
> {
> I+=4;
> return I;
> }
>
> [Java code]
>
> public class PointlessSpeedTest
> {
> public static void main (String[] args)
> {
> int i, j=-42;
> System.out.println("##### 500 Million Calls Speed Test #####");
> long START_TC=System.currentTimeMillis();
> for (i=0; i<500000000; i++) j=TCcall(i);
> long END_TC=System.currentTimeMillis();
> long START=System.currentTimeMillis();
> for (i=0; i<500000000; i++) j=Ccall(i);
> long END=System.currentTimeMillis();
> long start=System.currentTimeMillis();
> for(i=0; i<500000000; i++) j=i+4;
> long end=System.currentTimeMillis();
> System.out.println("(TryCatched) Elapsed: "+(END_TC-START_TC)+" ms");
> System.out.println("(!TryCatched) Elapsed: "+(END-START)+" ms");
> System.out.println("(Directly) Elapsed: "+(end-start)+" ms");
> }
>
> private static int TCcall(int I)
> {
> try
> {
> I+=4;
> return I;
> }
> catch(Exception ex) { return I; }
> }
>
> private static int Ccall(int I)
> {
> I+=4;
> return I;
> }
> }
>
>


May 23, 2004
There is some overhead in a function added if exception 'catcher' code exists. This is necessary in order to be compatible with Win32 structured exception handling. The linux version, however, does not have such overhead since it is based on static tables (though there is extra overhead based on the need to use EBP as a frame pointer). I think your sample code overstates the overhead, as it compares with a trivial function that can be optimized into two instructions, which is not at all typical of functions which need to generate exception frames.


May 23, 2004
I used the same code and I got a different result than you, which follows:

C:\Documents and Settings\me.ME\Desktop>javac PointlessSpeedTest.java

C:\Documents and Settings\me.ME\Desktop>java PointlessSpeedTest
##### 500 Million Calls Speed Test #####
(TryCatched) Elapsed: 5227 ms
(!TryCatched) Elapsed: 1913 ms
(Directly) Elapsed: 1973 ms

C:\Documents and Settings\me.ME\Desktop>dmd -O -release -inline test.d c:\dmd\bin\..\..\dm\bin\link.exe test,,,user32+kernel32/noi;

C:\Documents and Settings\me.ME\Desktop>test
 ##### 500 Million Calls Speed Test #####
(TryCatched) Elapsed (ms) : 6410
(!TryCatched) Elapsed (ms) : 911
(Directly) Elapsed (ms) : 611

I have WinXP pro with 256 megs ram and an Athlon 2100.

I will add that when I used to use Java, I used try catch to my advantage,
It saves hassles trying to get the length of an array for example, and you
dont need
to check the bounds at all, so its a bit faster in loops.

But with D's speed and the fantastic foreach it has, none of this is necessary.

Phill.






"Lord Syl" <Lord_member@pathlink.com> wrote in message news:c8ncf8$g3r$1@digitaldaemon.com...
> Hey, I just made a quick test, in order to see method calls' speed. When I compared the results to Java's, I found interesting that Java
(running
> via JVM) had beaten D in the Try-Catch exception handling speed area,
while
> running slow as hell in the rest.
>
> Here are the results:
>
> <[D] 500 Million Calls speed test >>
>
> TryCatched - 13750 ms
> !TryCatched - 1933 ms
> Directly - 1292 ms
>
> Compiler version is 0.90, with commandline -O -release -inline
>
> <[Java] 500 Million Calls speed test >>
>
> TryCatched - 10926 ms
> !TryCatched - 4406 ms
> Directly - 4597 ms
>
> Using Java VM v1.50 beta from Sun
>
> Tests were done on a Duron 800(6x133) processor with  640Mb@266Mhz RAM
under
> Windows XP.
>
> [D source code]
>
> import std.date;
> int main (char[][] args)
> {
> int i, j=-42;
> printf(" ##### 500 Million Calls Speed Test #####\n");
> long START_TC=getUTCtime();
> for (i=0; i<500000000; i++) j=TCcall(i);
> long END_TC=getUTCtime();
> long START=getUTCtime();
> for (i=0; i<500000000; i++) j=Ccall(i);
> long END=getUTCtime();
> long start=getUTCtime();
> for(i=0; i<500000000; i++) j=i+4;
> long end=getUTCtime();
> printf("(TryCatched) Elapsed (ms) : %d\n",(END_TC-START_TC));
> printf("(!TryCatched) Elapsed (ms) : %d\n",(END-START));
> printf("(Directly) Elapsed (ms) : %d\n",(end-start));
> return 0;
> }
>
> static final int TCcall(int I)
> {
> try
> {
> I+=4;
> return I;
> }
> catch(Error e) { return I; }
> }
>
> static final int Ccall(int I)
> {
> I+=4;
> return I;
> }
>
> [Java code]
>
> public class PointlessSpeedTest
> {
> public static void main (String[] args)
> {
> int i, j=-42;
> System.out.println("##### 500 Million Calls Speed Test #####");
> long START_TC=System.currentTimeMillis();
> for (i=0; i<500000000; i++) j=TCcall(i);
> long END_TC=System.currentTimeMillis();
> long START=System.currentTimeMillis();
> for (i=0; i<500000000; i++) j=Ccall(i);
> long END=System.currentTimeMillis();
> long start=System.currentTimeMillis();
> for(i=0; i<500000000; i++) j=i+4;
> long end=System.currentTimeMillis();
> System.out.println("(TryCatched) Elapsed: "+(END_TC-START_TC)+" ms");
> System.out.println("(!TryCatched) Elapsed: "+(END-START)+" ms");
> System.out.println("(Directly) Elapsed: "+(end-start)+" ms");
> }
>
> private static int TCcall(int I)
> {
> try
> {
> I+=4;
> return I;
> }
> catch(Exception ex) { return I; }
> }
>
> private static int Ccall(int I)
> {
> I+=4;
> return I;
> }
> }
>
>