среда, 1 февраля 2012 г.

Java vs Scala vs Groovy performance. Так кто же быстрее?

Несколько лет назад начал интересоваться альтернативными языками для JVM. Groovy даже нашёл своё применение в некоторых "живых" проектах. Однако плохая производительность сильно ограничивала использование языка в реальных приложениях.

Прошло несколько лет, появился Groovy 1.8, который, по заявлениям разработчиков, справился с проблемами производительности. Так ли это на самом деле? Чтобы ответить на этот вопрос, я написал примитивные тесты на 3-х популярных языках для JVM.

Groovy.
 static void main(args) {
    long l = System.currentTimeMillis()
    int cnt = 0;
    100000.times { i->
      //def customer = new Tester(id: i, name:"Gromit", dob:new Date())
      //String s = ("Hello ${customer.name} ${i}")
      String s = ("Hello  ${i} Groovy")
      cnt += s.length()
    }    
    println( "${System.currentTimeMillis() - l} - ${cnt}")
}
Результат - 438 миллисекунд. То же самое в Scala :
 
override def main(args: Array[String])  {
    val l = System.currentTimeMillis()
    var cnt = 0;
    for (i <- 0.until(100000)){
      val s = "Hello " + i + " Times scala"
      cnt += s.length()      
    }
    
    println((System.currentTimeMillis() - l) + " - " + cnt)
  }
187 миллисекунд, лучше более чем в 2 раза? И теперь чистая Java (версии 1.7):
 
public static void main(String [] args) {
    long l = System.currentTimeMillis();
    int len = 0;
    for(int i = 0; i < 100_000; i++){
      String s = "Hello " + i + " Java";
      len += s.length();
    }

    System.out.println( (System.currentTimeMillis() - l)+ " - " + len) ;
}
32 миллисекунды! более чем в 10 раз быстрее аналога на Groovy. Java заруливает всех своих JVM опонентов, если речь идёт о производительности.

4 комментария:

  1. Стало интересно проверить ваши тесты на своей машине. У нас в компании используется Java 1.6 и старый Groovy 1.6.4. В итоге результаты:
    groovy - 280
    java - 39

    Это, конечно, далеко от желаемого результата, но уже и не в 10 раз медленнее. А вообще, наверное, только по одному тесту и на одной конфигурации сложно судить о производительности языка. В других сравнених вон числа Фибоначчи вычисляют - там вроде бы при конфигурации более-менее похожей с вашей разница в производительности 12% получается. (http://www.wiki.jvmlangsummit.com/images/0/04/Theodorou-Faster-Groovy-1.8.pdf)

    Хотя, на мой взгляд, и этот тест является не совсем корректным, потому что область применения у этих языков несколько разная и сравнение получается холиварное прямо как Java vs C++, но в любом случае спасибо за статью :)

    ОтветитьУдалить
  2. Согласен, результаты теста сильно зависят от конфигурации и окружения.
    Для меня основным вопросом был "Удалось ли разработчикам Груви улучшить производительность"? К сожалению, Груви всё так же тормозит. Очень жаль, ибо сам язык очень интересен.

    Спасибо за коммент :) Если не секрет, почему "Java для белок"?

    ОтветитьУдалить
  3. у вас не оптимизированный код:
    100000.times{} - работает через замыкания
    лучше через обычный for


    я тестил у себя следующий код

    java version "1.6.0_26"
    Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
    Java HotSpot(TM) Server VM (build 20.1-b02, mixed mode)

    public class SpeedTestJava {
    public static void main(String[] args) {
    long start = System.currentTimeMillis();
    for(int i=0; i< 10000;i++){
    System.out.println(i);
    }
    System.out.println(System.currentTimeMillis() - start);
    }
    }

    результат 182


    groovy
    Groovy Version: 1.7.4 JVM: 1.6.0_26

    long start = System.currentTimeMillis()
    for(i in 0..10000){
    println i
    }
    println System.currentTimeMillis() - start

    результат 515

    в 2.8 раз разница! тем более версия груви не самая последняя )

    ОтветитьУдалить
  4. абсолютно нелепое сравнение - если вы бы на джава привели сходный код (реализовали бы антил и тд) - вы бы не писали эту глупость

    ОтветитьУдалить