A benchmark in various languages to get feel of the speed differences of modern language implementations when running straightforward integer and array code. The classic Sieve. Yes, I know very well that one should not draw too many conclusions from test like this, but it was interesting and educational, especially since I am not very familiar with all of the languages. As the header comments say, these are ported versions of http://rsb.info.nih.gov/nih-image/java/benchmarks/Sieve.java. The blog has mangled some of the indentation (Blogger does not seem to have a "preformatted" or "code" paragraph style), but I'm not going to beautify these here manually.
The benchmarks time themselves so that they run for 10 seconds, and report the number of rounds (so bigger number is better). I ran these about 5 times and took the median. The surprising result was that Java beat C++ (JDK 1.7 vs GCC 4.8.3), but try for yourself! I'm intentionally not giving my exact scores.
Java:
// Sieve benchmark, based on the code at
// http://rsb.info.nih.gov/nih-image/java/benchmarks/Sieve.java
// but modified to run without GUI.
// Also used "do {} while" loop instead of "while(true){...if() break;}".
// Surprisingly, the "do {} while" is noticeably faster.
// It also matters is SIZE is marked "final" or not. The "final" is
// about 30% faster!
public class sieve {
static void runSieve() {
final int SIZE = 8190;
boolean flags[] = new boolean[SIZE+1];
int i, prime, k, count;
int iterations = 0;
double seconds = 0.0;
int score = 0;
long startTime, elapsedTime;
startTime = System.currentTimeMillis();
do {
count=0;
for(i=0; i<=SIZE; i++) flags[i]=true;
for (i=0; i<=SIZE; i++) {
if(flags[i]) {
prime=i+i+3;
for(k=i+prime; k<=SIZE; k+=prime)
flags[k]=false;
count++;
}
}
iterations++;
elapsedTime = System.currentTimeMillis() - startTime;
} while (elapsedTime < 10000);
seconds = elapsedTime / 1000.0;
score = (int) Math.round(iterations / seconds);
System.out.println(iterations + " iterations in " + seconds + " seconds");
if (count != 1899)
System.out.println("Error: count <> 1899");
else
System.out.println("Sieve score = " + score);
}
public static void main(String[] args) {
runSieve();
}
}
C++:
// Sieve benchmark, based on the code at
// http://rsb.info.nih.gov/nih-image/java/benchmarks/Sieve.java
// but modified to run as a C++ program (for comparison with Java and
// JavaScript. Trying to keep the program as similar as possible to the
// language versions.
// Function round() avoided because Visual C++ (at least older versions)
// does not have it.
#include <stdio.h>
#include <time.h>
#include <math.h>
class sieve {
public:
static void runSieve() {
const int SIZE = 8190;
bool *flags = new bool[SIZE+1];
int i, prime, k, count;
int iterations = 0;
double seconds = 0.0;
int score = 0;
time_t startTime, elapsedTime, t0;
// Due to only 1s resolution, wait until the clock ticks before test
t0 = startTime = time(NULL);
while (startTime == t0)
startTime = time(NULL);
do {
count=0;
for(i=0; i<=SIZE; i++) flags[i]=true;
for (i=0; i<=SIZE; i++) {
if(flags[i]) {
prime=i+i+3;
for(k=i+prime; k<=SIZE; k+=prime)
flags[k]=false;
count++;
}
}
iterations++;
elapsedTime = time(NULL) - startTime;
} while (elapsedTime < 10);
seconds = (double)elapsedTime;
score = floor(iterations / seconds + 0.5);
printf("%d iterations in %6.3f seconds\n", iterations, seconds);
if (count != 1899)
printf("Error: count <> 1899\n");
else
printf("Sieve score = %d\n", score);
}
};
int main() {
sieve::runSieve();
return 0;
}
JavaScript (run in Node.js):
// http://rsb.info.nih.gov/nih-image/java/benchmarks/Sieve.java
// but modified to run in Javascript, inside node/js ("node sieve.js")
function runSieve() {
var SIZE = 8190;
var flags = new Array(SIZE);
var i, prime, k, count;
var iterations = 0;
var seconds = 0.0;
var score = 0;
var startTime, elapsedTime;
//startTime = System.currentTimeMillis();
startTime = Date.now();
do {
count=0;
for(i=0; i<=SIZE; i++) flags[i]=true;
for (i=0; i<=SIZE; i++) {
if(flags[i]) {
prime=i+i+3;
for(k=i+prime; k<=SIZE; k+=prime)
flags[k]=false;
count++;
}
}
iterations++;
elapsedTime = Date.now() - startTime;
} while (elapsedTime < 10000);
seconds = elapsedTime / 1000.0;
score = Math.round(iterations / seconds);
console.log(iterations + " iterations in " + seconds + " seconds");
if (count != 1899)
console.log("Error: count <> 1899");
else
console.log("Sieve score = " + score);
}
runSieve();
Python (2.7):
import time
def runSieve():
SIZE = 8190
flags = [None] * (SIZE+1)
i = 0;
prime = 0;
k = 0
count = 0
iterations = 0
seconds = 0.0
score = 0
startTime = 0
elapsedTime = 0
t0 = 0
# Due to only 1s resolution, wait until the clock ticks before test
startTime = time.clock();
t0 = startTime
while startTime == t0:
startTime = time.clock()
while elapsedTime < 10:
count=0;
#for i in range(SIZE):
# flags[i]=True
# This is faster array init than the above loop
flags = [True] * (SIZE+1)
for i in range(SIZE):
if flags[i]:
prime=i+i+3
k=i+prime
while k<=SIZE:
flags[k]=False
k+=prime
count+=1;
iterations+=1
elapsedTime = time.clock() - startTime
seconds = elapsedTime
score = round(iterations / seconds)
print "%d iterations in %6.3f seconds" % (iterations, seconds)
if count != 1899:
print "Error: count <> 1899"
else:
print "Sieve score = %d" % score
runSieve()
Perl:
## Sieve benchmark, based on the code at
## http://rsb.info.nih.gov/nih-image/java/benchmarks/Sieve.java
## but modified to run as perl program (for comparison with Java and
## JavaScript. Trying to keep the program as similar as possible to the
## language versions.
sub runSieve {
my $SIZE = 8190;
my @flag; $flags[$SIZE+1] = 0;
my ($i, $prime, $k, $count);
my $iterations = 0;
my $seconds = 0.0;
my $score = 0;
my ($startTime, $elapsedTime, $t0);
# Due to only 1s resolution, wait until the clock ticks before test
$startTime = time();
$t0 = $startTime;
while ($startTime == $t0) {
$startTime = time();
}
do {
$count=0;
for($i=0; $i<=$SIZE; $i++) {
$flags[$i]=1;
}
for ($i=0; $i<=$SIZE; $i++) {
if($flags[$i]) {
$prime=$i+$i+3;
for($k=$i+$prime; $k<=$SIZE; $k+=$prime) {
$flags[$k]=0;
}
$count++;
}
}
$iterations++;
$elapsedTime = time() - $startTime;
} while ($elapsedTime < 10);
$seconds = $elapsedTime + 0.0;
$score = int($iterations / $seconds + 0.5);
printf("%d iterations in %6.3f seconds\n", $iterations, $seconds);
if ($count != 1899) {
printf("Error: count <> 1899\n");
}
else {
printf("Sieve score = %d\n", $score);
}
}
runSieve();
Groovy:
// Sieve benchmark, based on the code at
// http://rsb.info.nih.gov/nih-image/java/benchmarks/Sieve.java
// but groovyized and modified to run without GUI.
// Groovy does not support do...while so that optimization for Java was
// undone.
// Much slower than either Java or JavaScript(on node/js) version.
def runSieve() {
final int SIZE = 8190;
boolean[] flags = new boolean[SIZE+1];
int i, prime, k, iter, count;
int iterations = 0;
double seconds = 0.0;
int score = 0;
long startTime, elapsedTime = 0;
startTime = System.currentTimeMillis();
while (elapsedTime < 10000) {
count=0;
for(i=0; i<=SIZE; i++) flags[i]=true;
for (i=0; i<=SIZE; i++) {
if(flags[i]) {
prime=i+i+3;
for(k=i+prime; k<=SIZE; k+=prime)
flags[k]=false;
count++;
}
}
iterations++;
elapsedTime = System.currentTimeMillis() - startTime;
}
seconds = elapsedTime / 1000.0;
score = (int) Math.round(iterations / seconds);
println(iterations + " iterations in " + seconds + " seconds");
if (count != 1899)
println("Error: count <> 1899");
else
println("Sieve score = " + score);
}
runSieve()