Performance Comparisons of Dynamic Languages
on the Java Virtual Machine
Michael Galpin, eBay
@michaelg
The Critical Factor When Choosing JVM Language?
SPEED
The End
Not Just Speed.
Stability
               ne ss
        sive
    res                       Man
E xp                              agea
     ...
Disclaimer
Disclaimer




I’m a Liar
Three Algorithms & Six Languages

• Prime Number Sieve           • Groovy


• Case Insensitive Word Sort   • JRuby


• Rev...
Three Algorithms & Six Languages

• Prime Number Sieve           • Groovy


• Case Insensitive Word Sort   • JRuby


• Rev...
Prime Number Sieve
public class Primes {
    final private List<Integer> primes;
    private final int size;

    public Primes(int n){
     ...
class RubyPrimes
  attr_accessor :cnt, :primes

  def initialize(n)
    @primes = Array.new(n,0)
    @cnt = 0
    i = 2
  ...
class PyPrimes(object):
    __slots__ = ['cnt','primes','size']

    def __init__(self,n):
        self.primes = n*[0]
   ...
Time / Java Time
class ScalaPrimes(val size:Int){
  val primes = new ArrayBuffer[Int]
  var cnt = 0
  init
  def last = primes(primes.size ...
class Primes {
  Int[] primes := Int[,]
  Int size

    new make(Int n) {
      size = n
      primes.capacity = n
      i...
Time / Java Time
Word Sort
public class WordSort {
    private final File dataFile;
    private final List<String> words;

    public WordSort(String...
public class GroovyWordSort {
  File dataFile
  List words = []

    public GroovyWordSort(fileName){
      dataFile = new...
class RubyWordSort

  def initialize(fileName)
    @dataFile = File.new(fileName)
    @words = Array.new
  end

  def sort...
class PyWordSort(object):

    def __init__(self, fileName):
        print quot;init quot; + fileName
        self.dataFil...
(defn word-sort [file-name]
    (with-open [r (new java.io.BufferedReader (new java.io.FileReader
    file-name))]
      (...
class ScalaWordSort(fileName:String){
  lazy val sortedWords = {
    Source.fromFile(dataFile).getLines.foreach(_.split(qu...
class WordSort {
  File? dataFile

    once Str[] getSortedWords() {
      words := Str[,]
      dataFile.eachLine |line| ...
Time / Java Time
Reversible Numbers
WTF is a Reversible Number?



Some positive integers n have the property that the sum [ n + reverse(n) ] consists entirel...
public class Reversible {
    final int max;
    final int numReversible;

    public Reversible(int max){
        this.ma...
public class GroovyReversible {
  final Integer max
  final Integer numReversible = 0

    public GroovyReversible(max){
 ...
class RubyReversible
  def initialize(max)
    @max = max
    @numReversible = nil
  end

  def allOdd(n)
    digits = n.t...
class PyReversible(object):
    __slots__ = ['max','numReversible']

    def __init__(self, max):
        self.max = max
 ...
(defn all-odd? [n]
  (every? odd? (map #(Integer. (str %)) (str n))))

(defn reverse-num [n]
  (+ n (Integer. (apply str (...
class ScalaReversible(max:Int){
  lazy val numReversible = (11 to max).filter(reversible(_)).size
  private
  def reverse(...
class Reversible {
  Int max

    once Int   countReversible() {
      cnt :=   0
      for (i   := 11; i<=max; i++) if (r...
Time / Java Time
So What Now?
Questions?
Performance Comparisons of Dynamic Languages on the Java Virtual Machine
Upcoming SlideShare
Loading in …5
×

Performance Comparisons of Dynamic Languages on the Java Virtual Machine

5,972 views
5,520 views

Published on

Session Abstract: It is an exciting time for developing applications that run on the Java™ Virtual Machine (JVM™ machine), because you have more choices than ever. You can take your pick of languages such as Python, Ruby, Groovy, and Scala for writing your applications while still leveraging the power of the JVM machine. However, what are the performance trade-offs? This session, for developers who want to use alternative languages on the JVM machine, looks at implementing various algorithms in each of these languages and compares how well they perform on the JVM machine. It discusses the characteristics of each language and how they influence performance results. It also throws in pure Java technology-based implementations of these algorithms as well as “native” performance for languages such as Python and Ruby. Some of the results can be very surprising.

Published in: Art & Photos, Technology
0 Comments
9 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
5,972
On SlideShare
0
From Embeds
0
Number of Embeds
549
Actions
Shares
0
Downloads
198
Comments
0
Likes
9
Embeds 0
No embeds

No notes for slide








































  • Performance Comparisons of Dynamic Languages on the Java Virtual Machine

    1. Performance Comparisons of Dynamic Languages on the Java Virtual Machine Michael Galpin, eBay @michaelg
    2. The Critical Factor When Choosing JVM Language?
    3. SPEED
    4. The End
    5. Not Just Speed.
    6. Stability ne ss sive res Man E xp agea bility Not Just Speed. Comm To ol y Jo s unity
    7. Disclaimer
    8. Disclaimer I’m a Liar
    9. Three Algorithms & Six Languages • Prime Number Sieve • Groovy • Case Insensitive Word Sort • JRuby • Reversible Numbers • Jython • Clojure • Scala • Fan
    10. Three Algorithms & Six Languages • Prime Number Sieve • Groovy • Case Insensitive Word Sort • JRuby • Reversible Numbers • Jython • Clojure • Scala • Fan
    11. Prime Number Sieve
    12. public class Primes { final private List<Integer> primes; private final int size; public Primes(int n){ size = n; primes = new ArrayList<Integer>(n); init(); } private void init(){ int i=2; int max = calcSize(); List<Boolean> nums = new ArrayList<Boolean>(max); for (int j=0;j<max;j++){ nums.add(true); } while (i < max && primes.size() < size){ int p = i; if (nums.get(i)){ primes.add(p); int j = 2*p; while (j < max - p){ nums.set(j,false); j += p; } } i += 1; } } public int last(){ return primes.get(primes.size()-1); } private int calcSize(){ int max = 2; while ((max/Math.log(max)) < size && max < Integer.MAX_VALUE && max > 0){ max *=2; } return max; } }
    13. class RubyPrimes attr_accessor :cnt, :primes def initialize(n) @primes = Array.new(n,0) @cnt = 0 i = 2 max = calcSize nums = Array.new(max,true) while (i < max && @cnt < @primes.length) p = i if (nums[i]) @primes[@cnt] = p @cnt += 1 (p .. (max/p)).each{ |j| nums[p*j] = false } end i += 1 end end def calcSize max = 2 max = max * 2 while ( max/Math.log(max) < @primes.length) max end def last @primes[@cnt -1] end end
    14. class PyPrimes(object): __slots__ = ['cnt','primes','size'] def __init__(self,n): self.primes = n*[0] self.cnt = 0 self.size = n i = 2 max = self.calcSize() nums = max*[True] while i < max and self.cnt < self.size: p = i if nums[i]: self.primes[self.cnt] = p self.cnt += 1 for j in xrange(p, max/p): nums[p*j] = False i+= 1 def calcSize(self): max = 2 while max/log(max) < self.size: max = max *2 # this makes the sieve too big, but fast return max def last(self): return self.primes[self.cnt - 1]
    15. Time / Java Time
    16. class ScalaPrimes(val size:Int){ val primes = new ArrayBuffer[Int] var cnt = 0 init def last = primes(primes.size - 1) private def init { var i = 2 val max = calcSize val nums = new ArrayBuffer[Boolean] for (i<-0 until max) nums += true while (i < max && cnt < size){ val p = i if (nums(i)){ primes += p cnt += 1 (p until max/p).foreach((j) => nums.update(p*j,false)) } i += 1 } } def calcSize = { var max = 2 while ( (max/log(max)) < size && max < MAX_VALUE && max > 0) { max *= 2 } max } }
    17. class Primes { Int[] primes := Int[,] Int size new make(Int n) { size = n primes.capacity = n init } private Void init() { i := 2 max := calcSize nums := Bool[,] nums.fill(true, max) while (i < max && primes.size < size) { p := i if (nums[i]) { primes.add(p) j := 2*p; while (j < max - p) { nums[j] = false j += p; } } i += 1; } } Int last() { primes.last } private Int calcSize() { max := 2 while ((max.toFloat/max.toFloat.log).toInt < size && max < 0x7fff_ffff && max > 0) { max *=2; // memory inefficient, but fast } return max; } }
    18. Time / Java Time
    19. Word Sort
    20. public class WordSort { private final File dataFile; private final List<String> words; public WordSort(String fileName){ dataFile = new File(fileName); int idx = fileName.lastIndexOf(quot;/quot;); String name = fileName.substring(idx+1, fileName.length() - 4); int numWords = Integer.parseInt(name); words = new ArrayList<String>(numWords); } public List<String> getSortedWords(){ if (words.size() > 0){ return words; } try { BufferedReader reader = new BufferedReader(new FileReader(dataFile)); try{ String line; while ( (line = reader.readLine()) != null){ for (String string : line.split(quot; quot;)){ words.add(string); } } } finally { reader.close(); } Collections.sort(words, new Comparator<String>(){ public int compare(String s, String s1) { return s.toLowerCase().compareTo(s1.toLowerCase()); } }); return words; } catch (IOException e) { throw new RuntimeException(e); } } }
    21. public class GroovyWordSort { File dataFile List words = [] public GroovyWordSort(fileName){ dataFile = new File(fileName) } def sortedWords(){ if (!words){ dataFile.eachLine{it.tokenize().each {words.add(it) }} words = words.sort{w,w1 -> w.toLowerCase() <=> w1.toLowerCase()} } words } }
    22. class RubyWordSort def initialize(fileName) @dataFile = File.new(fileName) @words = Array.new end def sortedWorts if (@words.length == 0) @dataFile.each_line{ |line| line.split(' ').each{ |word| @words << word}} @words = @words.sort{ |w,w1| w.upcase <=> w1.upcase } end @words end end
    23. class PyWordSort(object): def __init__(self, fileName): print quot;init quot; + fileName self.dataFile = open(fileName) self.words = [] def sortedWords(self): if len(self.words) == 0: for line in self.dataFile: for word in line.split(): self.words.append(word) self.words.sort(lambda w,w1: cmp(w.lower(), w1.lower())) return self.words
    24. (defn word-sort [file-name] (with-open [r (new java.io.BufferedReader (new java.io.FileReader file-name))] (sort-by #(.toLowerCase #^String %) (mapcat #(.split #^String % quot; quot;) (line-seq r)))))
    25. class ScalaWordSort(fileName:String){ lazy val sortedWords = { Source.fromFile(dataFile).getLines.foreach(_.split(quot; quot;).foreach(words ::= _)) words.sort(_.toLowerCase < _.toLowerCase) } private val dataFile = new File(fileName) var words:List[String] = Nil }
    26. class WordSort { File? dataFile once Str[] getSortedWords() { words := Str[,] dataFile.eachLine |line| { words.addAll(line.split) } return words.sort |a, b| { a.compareIgnoreCase(b) } } }
    27. Time / Java Time
    28. Reversible Numbers
    29. WTF is a Reversible Number? Some positive integers n have the property that the sum [ n + reverse(n) ] consists entirely of odd (decimal) digits. For instance, 36 + 63 = 99 and 409 + 904 = 1313. We will call such numbers reversible; so 36, 63, 409, and 904 are reversible. Leading zeroes are not allowed in either n or reverse(n). There are 120 reversible numbers below one-thousand.
    30. public class Reversible { final int max; final int numReversible; public Reversible(int max){ this.max = max; this.numReversible = this.countReversible(); } public int countReversible(){ if (numReversible > 0){ return numReversible; } int cnt = 0; for (int i=11;i<=max;i++){ if (reversible(i)) { cnt++; } } return cnt; } private boolean reversible(int n){ return allOdd(reverse(n)); } private boolean allOdd(int n){ String str = Integer.toString(n); for (int i=0;i<str.length();i++){ int m = Character.digit(str.charAt(i),10); if (m % 2 == 0) return false; } return true; } private int reverse(Integer n){ char[] digits = n.toString().toCharArray(); char[] rev = new char[digits.length]; for (int i=digits.length-1;i>=0;i--){ rev[i] = digits[digits.length -i-1]; } return n + Integer.parseInt(String.valueOf(rev)); } }
    31. public class GroovyReversible { final Integer max final Integer numReversible = 0 public GroovyReversible(max){ this.max = max this.numReversible = this.countReversible() } def countReversible(){ numReversible ?: (11..max).findAll{reversible(it)}.size() } def reversible(n){ allOdd(reverse(n)) } def allOdd(n){ n.toString().toList().collect {it.toInteger()}.every{it % 2 == 1} } def reverse(n){ n + n.toString().toList().reverse().join().toInteger() } }
    32. class RubyReversible def initialize(max) @max = max @numReversible = nil end def allOdd(n) digits = n.to_s.split(//) digits.length == digits.map{|c| c.to_i}.select{|i| i % 2 == 1}.length end def reverse(n) n + n.to_s.reverse.to_i end def reversible(n) allOdd(reverse(n)) end def countReversible() @numReversible ||= (11..@max).select{|i| reversible(i)}.length @numReversible end end
    33. class PyReversible(object): __slots__ = ['max','numReversible'] def __init__(self, max): self.max = max self.numReversible = self.countReversible() def countReversible(self): return len([i for i in xrange(11,self.max+1) if self.reversible(i)]) def allOdd(self,n): for ch in str(n): if int(ch) % 2 != 1: return False return True def reverse(self,n): return n + int(str(n)[::-1]) def reversible(self,n): return self.allOdd(self.reverse(n))
    34. (defn all-odd? [n] (every? odd? (map #(Integer. (str %)) (str n)))) (defn reverse-num [n] (+ n (Integer. (apply str (reverse (str n)))))) (defn reversible-num? [n] (all-odd? (reverse-num n))) (defn count-reversible [rev-max] {:max rev-max :num-reversible (count (filter reversible-num? (range 11 rev-max)))})
    35. class ScalaReversible(max:Int){ lazy val numReversible = (11 to max).filter(reversible(_)).size private def reverse(n:Int)=n + parseInt(n.toString.reverse) def allOdd(n:Int) = n.toString.map(digit(_,10)).forall(_ % 2 == 1) def reversible(n:Int) = allOdd(reverse(n))
    36. class Reversible { Int max once Int countReversible() { cnt := 0 for (i := 11; i<=max; i++) if (reversible(i)) cnt++ return cnt } private Bool reversible(Int n) { allOdd(reverse(n)) } private Bool allOdd(Int n) { n.toStr.all |char| { char.isOdd } } private Int reverse(Int n) { n + n.toStr.reverse.toInt } }
    37. Time / Java Time
    38. So What Now?
    39. Questions?

    ×