Перш за все, я хотів би дати зрозуміти, що це не питання "мова-X проти мови-Y", щоб визначити, що краще.
Я використовую Java вже давно і маю намір продовжувати її використовувати. Паралельно з цим, я зараз навчаюсь Scala з великим інтересом: крім незначних речей, які дещо звикають до мого враження, це те, що я справді можу дуже добре працювати цією мовою.
Моє запитання: як програмне забезпечення, написане на Scala, порівнюється з програмним забезпеченням, написаним на Java, за швидкістю виконання та витратою пам'яті? Звичайно, на це важко відповісти на загальне питання, але я би сподівався, що конструкції вищого рівня, такі як відповідність шаблонів, функції вищого порядку тощо, введуть певні накладні витрати.
Однак мій сучасний досвід роботи в Scala обмежений невеликими прикладами під 50 рядками коду, і я досі не використовував жодних орієнтирів. Отже, у мене немає реальних даних.
Якщо виявилося, що у Scala є якась накладна wrt Java, чи є сенс мати змішані проекти Scala / Java, де кодуються складніші частини Scala та критично важливі частини Java? Це звичайна практика?
ЗРІД 1
Я запустив невеликий орієнтир: складіть список цілих чисел, помножте кожне ціле число на два і покладіть його в новий список, надрукуйте отриманий список. Я написав реалізацію Java (Java 6) та реалізацію Scala (Scala 2.9). Я працював на Eclipse Indigo під Ubuntu 10.04.
Результати порівнянні: 480 мс для Java та 493 мс для Scala (в середньому понад 100 ітерацій). Ось фрагменти, які я використав.
// Java
public static void main(String[] args)
{
long total = 0;
final int maxCount = 100;
for (int count = 0; count < maxCount; count++)
{
final long t1 = System.currentTimeMillis();
final int max = 20000;
final List<Integer> list = new ArrayList<Integer>();
for (int index = 1; index <= max; index++)
{
list.add(index);
}
final List<Integer> doub = new ArrayList<Integer>();
for (Integer value : list)
{
doub.add(value * 2);
}
for (Integer value : doub)
{
System.out.println(value);
}
final long t2 = System.currentTimeMillis();
System.out.println("Elapsed milliseconds: " + (t2 - t1));
total += t2 - t1;
}
System.out.println("Average milliseconds: " + (total / maxCount));
}
// Scala
def main(args: Array[String])
{
var total: Long = 0
val maxCount = 100
for (i <- 1 to maxCount)
{
val t1 = System.currentTimeMillis()
val list = (1 to 20000) toList
val doub = list map { n: Int => 2 * n }
doub foreach ( println )
val t2 = System.currentTimeMillis()
println("Elapsed milliseconds: " + (t2 - t1))
total = total + (t2 - t1)
}
println("Average milliseconds: " + (total / maxCount))
}
Отже, в цьому випадку здається, що накладні витрати Scala (використовуючи дальність, карту, лямбда) дійсно мінімальні, що не далеко від інформації, яку надає World Engineer.
Можливо, є інші конструкції Scala, які слід обережно використовувати, оскільки вони особливо важкі для виконання?
EDIT 2
Деякі з вас вказали, що println у внутрішніх петлях займає більшу частину часу виконання. Я видалив їх і встановив розмір списків 100000 замість 20000. Отримане середнє значення склало 88 мс для Java та 49 мс для Scala.