DMelt:Programming/Benchmarks
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.
Groovy is a factor 10 faster than the standard Python or JRuby. The latter has a similar speed as the Python). |
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.