DMelt:Programming/Benchmarks

From HandWiki
Jump to: navigation, search
Limitted access. First login to DataMelt if you are a full DataMelt member. Then login to HandWiki as a user.

Benchmarking supported languages

You should make a smart choice what program language you should use for your project. If you are doing a lot of numeric computations and want to use scripting, use Groovy.

Jython and BeanShell can only be used if you manipulate with high-level libraries. Another choice is to implement code in Java, make a library, and call it from Jython and BeanShell.

Let us illustrate the speed of the executions. I'll benchmark a Monte Carlo calculation of PI (3.14159) by throwing "darts". The calculations are implemented in Java, Groovy, BeanShell, JRuby, Jython and Python (Python2 implemented in C).

Here is the original Java code "MonteCarloPI.java":

public class MonteCarloPI {
     public static void main(String[] args)
       {
         int nThrows = 0;
         int nSuccess = 0;
         double x, y;
         long then = System.nanoTime();
         int events=(int)1e8;
         for (int i = 0; i < events; i++) {
            x = Math.random();      // Throw a dart
            y = Math.random();
            nThrows++;
            if ( x*x + y*y <= 1 )  nSuccess++;
       }
 int itime = (int)((System.nanoTime() - then)/1e9);
 System.out.println("Time for calculations (sec): " + itime+"\n");
 System.out.println("Pi = " + 4*(double)nSuccess/(double)nThrows +"\n");
      }
}

Here is a Groovy code put to a file "MonteCarloPI.groovy":

int nThrows = 0; int nSuccess = 0;
double x, y;
long then = System.nanoTime();
int events=(int)1e8;
for (int i = 0; i < events; i++)   {
   x = Math.random(); y = Math.random();     // Throw a dart                   
   nThrows++;
   if ( x*x + y*y <= 1 )  nSuccess++;
}
int itime = (int)((System.nanoTime() - then)/1e9);
System.out.println("Time for calculations (sec): " + itime+"\n");
System.out.println("Pi = " + 4*(float)nSuccess/(float)nThrows +"\n");

Here is the JRuby code "MonteCarloPI.rb":

require "java"
java_import java.lang.Math;
java_import java.lang.System;
nThrows = 0; nSuccess = 0;
xthen = System.nanoTime();
events=1e8;
for i  in 0 .. events do
   x = Math.random(); y = Math.random();     #  Throw a dart                   
   nThrows +=1
   if ( x*x + y*y <= 1 )
                nSuccess += 1
  end
end
itime = (System.nanoTime() - xthen)/1e9;
xpi=(4.0*nSuccess)/nThrows
puts "Time for calculations (sec):  #{itime}"
puts "Pi = #{xpi}"

And here is a Jython code "MonteCarloPI.py":

from java.util import Random
from java.lang import *

nThrows,nSuccess = 0,0
then = System.nanoTime()
events=int(1e8)
for i in xrange(events):
    x,y = Math.random(),Math.random();      # Throw a dart                   
    nThrows +=1
    if ( x*x + y*y <= 1 ):  nSuccess+=1
itime = (int)((System.nanoTime() - then)/1e9)
print "Time for calculations (sec): ",itime
print "Pi = ", 4*nSuccess/float(nThrows)

Note we use "xrange" instead of "range". The calculations that use "range" are very slow in Jython and cannot be used in this instance.

I've renamed "MonteCarloPI.groovy" to a BeanShell script file "MonteCarloPI.bsh" (BeanShell has a very similar syntax as Groovy)

In the case of the standard Python, the code is "MonteCarloPI_CPython.py" looks as this:

import random
import time

nThrows,nSuccess = 0,0
then = time.time()
events=int(1e8)
for i in range(events):
    x,y = random.random(),random.random();      # Throw a dart                   
    nThrows +=1
    if ( x*x + y*y <= 1 ):  nSuccess+=1
itime = time.time() - then
print "Time for calculations (sec): ",itime
print "Pi = ", 4*nSuccess/float(nThrows)

Let us run "MonteCarloPI.java", "MonteCarloPI.groovy", "MonteCarloPI.py", MonteCarloPI.rb and "MonteCarloPI.bsh" inside DataMelt editor. Here is the benchmark results on a i7 x64 computer (Linux Mint), with 2048 MB allocated for JDK9 when running Groovy, Jython, BeanShell code:

Java   code:   3 sec Pi = 3.14176584  -> executed in DataMelt/JDK9
Groovy code:   3 sec Pi = 3.14144832  -> executed in DataMelt/JDK9
Python code:   3 sec Pi = 3.14188036  -> executed using PyPy
Groovy code:  14 sec Pi = 3.14141132  -> when using loose types for x,y 
Python code:  28 sec Pi = 3.14188036  -> executed in Python (CPython)
JRuby  code:  31 sec Pi = 3.14187860  -> executed in DataMelt/JDK9
Jython code:  40 sec Pi = 3.14187860  -> executed in DataMelt/JDK9
BeanShell code: takes forever?!       -> executed in DataMelt/JDK9

As you can see, Java and Groovy calculations take about the same time (3 sec). Python and JRuby is a factor 10 slower than Java and Groovy.