tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From André Warnier ...@ice-sa.com>
Subject Re: [OT] Setting HTTP response headers caching for 1 year doesn't work
Date Wed, 19 Jan 2011 11:52:14 GMT
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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Mime
View raw message