Christopher Schultz wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

André,

(You always make me write so much code!)

I don't /make/ you write code, I just provide the inspiration.
I'm quite good at that, when I don't have to do the work myself.
Thanks for writing the code in question though, it is nice getting to the 
bottom of an issue.

About this :
> Note that it's the Java compiler not the runtime that fails to deliver
> an error. The compiled C code happily overflows without any warning. Had
> I written the code using an array to store the operands and used an int
> to store the temporary result, you'd see the same truncation behavior
> with no compiler warnings. The fact that constants are being used are
> allowing the compiler to complain in this case.

Nitpick:
I am not sure that it is the use of constants that allows the compiler to 
complain.
Let's check that with a sample freely adapted from yours:

#include <stdio.h>

int main(int argc, char *argv[]) {

int thousand = 1000;
int sixty = 60;
int twentyfour = 24;
int hundred = 100;
int three = 3;

  int cacheTime1 = (1000 * 60 * 60 * 24 * 100 * 3);
  long cacheTime2 = ((long)1000 * 60 * 60 * 24 * 100 * 3);
  long long cacheTime3 = ((long long)1000 * 60 * 60 * 24 * 100 * 3);
  long long cacheTime4 = (1000 * 60 * 60 * 24 * 100 * (long long)3);
  long long cacheTime5 = (thousand * sixty * sixty * twentyfour * hundred * 
three);

  printf("%d\n%ld\n%lld\n%lld\n%lld\n", cacheTime1, cacheTime2, cacheTime3,
cacheTime4,cacheTime5);

  return 0;
}

aw@arthur:~/tests$ cc -ansi -pedantic -Wall -o longtime2 longtime2.c && 
./longtime2
longtime2.c: In function 'main':
longtime2.c:11: warning: integer overflow in expression
longtime2.c:12: warning: integer overflow in expression
longtime2.c:13: warning: ISO C90 does not support 'long long'
longtime2.c:13: warning: ISO C90 does not support 'long long'
longtime2.c:14: warning: ISO C90 does not support 'long long'
longtime2.c:14: warning: integer overflow in expression        <=== ****
longtime2.c:14: warning: ISO C90 does not support 'long long'
longtime2.c:15: warning: ISO C90 does not support 'long long'
longtime2.c:18: warning: ISO C90 does not support the 'll' printf length 
modifier
longtime2.c:18: warning: ISO C90 does not support the 'll' printf length 
modifier
longtime2.c:18: warning: ISO C90 does not support the 'll' printf length 
modifier
150196224
150196224
25920000000
150196224
150196224

Aha. So, it seems that the C compiler is smart enough to see that, potentially, multiplying an int variable by an int /might/ generate an overflow. Or else, it is smart enough to see that the defined int variables are in fact never modified in the scope of the function, and it internally optimises them as int constants, and then complains.
Either way, it is smart.

Maybe the Java compiler cannot afford to do that, because it is used in "just-in-time" compilations ?

...


$ time ./divisionSpeedTest.pl

 2 wallclock secs ( 1.50 usr +  0.06 sys =  1.56 CPU) @ 64102564.10/s
(n=100000000)
real    0m46.252s
user    0m45.924s
sys     0m0.326s

****

I couldn't make head or tail out of the timeit() function's return
value, so I just used 'time' from the command line to see what really
happened.

Neither could I, so I rewrote your test program somewhat (and decreased the loop by a factor 10, to be practical):
#!/usr/bin/perl

use Benchmark;

my $loops = 10000000;
NORMAL:{
my $left = 10;
my $right = 3;
my $res = $left / $right;
print "\'NORMAL\' result : $res\n";
my $t0 = Benchmark->new;
for (my $i=0; $i<$loops; $i++) {
  my $res = $left / $right;
}
my $t1 = Benchmark->new;
my $td = timediff($t1, $t0);
print "\'NORMAL\' times :",timestr($td),"\n";
}

INTEGER:{
use integer;
my $left = 10;
my $right = 3;
my $res = $left / $right;
print "\'INTEGER\' result : $res\n";
my $t0 = Benchmark->new;
for (my $i=0; $i<$loops; $i++) {
  my $res = $left / $right;
}
my $t1 = Benchmark->new;
my $td = timediff($t1, $t0);
print "\'INTEGER\' times :",timestr($td),"\n";
}

FLOAT:{
# Note: not really different from the above NORMAL
my $left = 10.0;
my $right = 3.0;
my $res = $left / $right;
print "\'FLOAT\' result : $res\n";
my $t0 = Benchmark->new;
for (my $i=0; $i<$loops; $i++) {
  my $res = $left / $right;
}
my $t1 = Benchmark->new;
my $td = timediff($t1, $t0);
print "\'FLOAT\' times :",timestr($td),"\n";
}

BIGFLOAT:{
use Math::BigFloat;
my $left = Math::BigFloat->new(10.0);
my $right = Math::BigFloat->new(3.0);
my $res = $left / $right;
print "\'BIGFLOAT\' result : $res\n";
my $t0 = Benchmark->new;
for (my $i=0; $i<$loops; $i++) {
  my $res = $left / $right;
}
my $t1 = Benchmark->new;
my $td = timediff($t1, $t0);
print "\'BIGFLOAT\' times :",timestr($td),"\n";
}

BIGINT:{
use bigint;
my $left = 10;
my $right = 3;
my $res = $left / $right;
print "\'BIGINT\' result : $res\n";
my $t0 = Benchmark->new;
for (my $i=0; $i<$loops; $i++) {
  my $res = $left / $right;
}
my $t1 = Benchmark->new;
my $td = timediff($t1, $t0);
print "\'BIGINT\' times :",timestr($td),"\n";
}

exit 0;


Note that for the BIGFLOAT and BIGINT sections, you need to be *really* patient.
I interrupted at after maybe 10 minutes..

Funny thing is, the INTEGER section seems actually slower than the standard one.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to