Saturday, 22 March 2014

Programming language (micro) benchmark

Out of curiosity, arising from a discussion on the Raspberry Pi forum, I did some micro benchmarking of C, Java and Python programming languages on Raspberry Pi. The application loops through numbers from 3 to 10000 and checks whether it is a prime number. I tried my best to make the code as close the same in all three languages (even not using boolean types) and eliminate any interference like console output. Also I did repeat the tests multiple times; seeing only some milliseconds deviation between runs.

Python code:
result = 0
result |= 2
for i in range(3,10001):
    prime = 1
    for j in range(2, i):
        k = i/j
        l = k*j
        if l == i:
            prime = 0
    if prime == 1:
        result |= i
print result

Saved as prime2.py and ran timing the execution:
$ time python prime2.py
16383

real    8m25.081s
user    8m7.960s
sys     0m1.230s

$ python --version
Python 2.7.3
...yes, that is 8 and a half minutes.

C code (repeats the test function 10 times to match Java...):
#include  <stdio.h>
int test() {
  int result = 0;
  result |= 2;
  int i;
  for (i=3;i<=10000;i++) {
    int prime = 1;
    int j;
    for (j=2;j<i;j++) {
      int k = i/j;
      int l = k*j;
      if (l==i) prime = 0;
    }
    if (prime) result |= i;
  }
  printf("%i\n", result);
}

int main() {
  int i;
  for (i = 0; i < 10; i++) {
    test();
  }
}

Saved as prime2.c, compiled with gcc -O2 -o prime2 prime2.c (with typical optimisation level 2) and ran:
$ time ./prime2
16383
16383
16383
16383
16383
16383
16383
16383
16383
16383

real    0m35.957s
user    0m35.780s
sys     0m0.070s

$ gcc --version
gcc (Debian 4.6.3-14+rpi1) 4.6.3
...which is 36 seconds for 10 rounds = less than 4 seconds for the same one round as in Python... (gcc (Debian 4.6.3-14+rpi1) 4.6.3)

Java code (repeats the test function 10 times to eliminate the effect of virtual machine start up time and possibly give the Hotspot compiler a chance to kick in):
public class Prime2 {

  public static void main(String [] args) {
    for (int i = 0; i < 10; i++) {
      test();
    }
  }

  public static void test() {
    int result = 0;
    result |= 2;
    for (int i=3;i<=10000;i++) {
      boolean prime = true;
      for (int j=2;j<i;j++) {
        int k = i/j;
        int l = k*j;
        if (l==i) prime = false;
      }
      if (prime) result |= i;
    }
    System.out.println(result);
  }
}

Saved as Prime2.java, compiled with javac Prime2.java and ran:
$ time java Prime2
16383
16383
16383
16383
16383
16383
16383
16383
16383
16383

real    0m33.490s
user    0m33.130s
sys     0m0.240s

$ java -version
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b36e)
Java HotSpot(TM) Client VM (build 25.0-b04, mixed mode)
...which is pretty impressive - even slightly faster than C - the Oracle guys have done a good job with optimising the Java platform for RPi.

Of course this is just a micro benchmark and one cannot draw too definite conclusions from the results. Also there are other aspects (accessibility, productivity, availability of domain specific libraries etc.) to consider when choosing a programming language.

No comments:

Post a Comment

Note: only a member of this blog may post a comment.