I couldn't resist to do a few of the most obvious optimizations for the C version which made the 100k test now take 0.3s on my machine (5 times faster than the C version in the question, both compiled with MSVC 2010 /Ox).
int isprime( int x )
{
int i, n;
for( i = 3, n = x >> 1; i <= n; i += 2 )
if( x % i == 0 )
return 0;
return 1;
}
void findprimes( int m )
{
int i, s = 3; // s is bitmask of primes in last 3 odd numbers
for( i = 11; i < m; i += 2, s >>= 1 ) {
if( isprime( i ) ) {
if( s & 1 )
printf( "%d %d\n", i - 6, i );
s |= 1 << 3;
}
}
}
main() {
findprimes( 10 * 1000 );
}
Here is the identical implemention in Java:
public class prime
{
private static boolean isprime( final int x )
{
for( int i = 3, n = x >> 1; i <= n; i += 2 )
if( x % i == 0 )
return false;
return true;
}
private static void findprimes( final int m )
{
int s = 3; // s is bitmask of primes in last 3 odd numbers
for( int i = 11; i < m; i += 2, s >>= 1 ) {
if( isprime( i ) ) {
if( ( s & 1 ) != 0 )
print( i );
s |= 1 << 3;
}
}
}
private static void print( int i )
{
System.out.println( ( i - 6 ) + " " + i );
}
public static void main( String[] args )
{
// findprimes( 300 * 1000 ); // for some JIT training
long time = System.nanoTime();
findprimes( 10 * 1000 );
time = System.nanoTime() - time;
System.err.println( "time: " + ( time / 10000 ) / 100.0 + "ms" );
}
}
With Java 1.7.0_04 this runs almost exactly as fast as the C version. Client or server VM doesn't show much difference, except that JIT training seems to help the server VM a bit (~3%) while it has almost no effect with the client VM. The output in Java seems to be slower than in C. If the output is replaced with a static counter in both versions, the Java version runs a little faster than the C version.
These are my times for the 100k run:
- 319ms C compiled with /Ox and output to >NIL:
- 312ms C compiled with /Ox and static counter
- 324ms Java client VM with output to >NIL:
- 299ms Java client VM with static counter
and the 1M run (16386 results):
- 24.95s C compiled with /Ox and static counter
- 25.08s Java client VM with static counter
- 24.86s Java server VM with static counter
While this does not really answer your questions, it shows that small tweaks can have a noteworthy impact on performance. So to be able to really compare languages you should try to avoid all algorithmic differences as much as possible.
It also gives a hint why Scala seems rather fast. It runs on the Java VM and thus benefits from its impressive performance.