О производительности и совместимости с Java: Clojure против Scala

82

Я уже читал различные отчеты о Clojure vs. Scala и пока понимаю, что оба имеют свое место. Есть несколько моментов, по которым я не получил полного объяснения, когда дело доходит до сравнения Clojure и Scala:

1.) Какой из двух языков вообще быстрее ? Я понимаю, что это будет отличаться от одной языковой функции к другой, но общая оценка производительности будет полезна. Например: я знаю, что словари Python действительно быстрые. Но в целом это намного более медленный язык, чем Java. Я не хочу идти с Clojure и сталкиваться с этой проблемой в будущем.

2.) Какова совместимость с Java? Все, что я прочитал до сих пор, - это то, что Scala имеет собственные типы коллекций, которые делают его немного неуклюжим для интеграции с большой базой кода Java, тогда как Clojure следует простому Iterable / Iterator-центричному способу взаимодействия с классами Java. Есть еще мысли / подробности по этому поводу?

В конце концов, если между clojure и scala есть достаточно близкое сходство, я могу попробовать их оба. Что касается Clojure, язык кажется очень простым. Но опять же, в Scala очень гибкая система типов. Но я знаю, что Scala работает быстро (на основе нескольких личных учетных записей). Итак, если Clojure значительно медленнее: я хотел бы знать раньше, чем позже.

Райан Делукки
источник
1
В Clojure 1.2 Clojure может вызывать java без дополнительных затрат. Посмотрите Assembla.com/wiki/show/clojure/Datatypes и Assembla.com/wiki/show/clojure/New_new . Это сделано потому, что Clojure хочет быть ближе к Java, но реализовано на Clojure.
nickik

Ответы:

73

Думаю, вам подойдет любой язык. При сравнении Python и Java кажется немного неразумным обвинять язык в разнице в скорости. Java компилируется JIT (кроме мобильных устройств *), тогда как Python интерпретируется. Тот факт, что оба используют байт-код, не означает, что реализации будут иметь даже отдаленно сопоставимую производительность. Но и Scala, и Clojure являются языками JVM, поэтому они должны иметь одинаковую производительность.

Scala имеет несколько преимуществ в реализации по сравнению с Clojure, и я ожидал бы более высокой производительности. Хотя статическая типизация Scala обычно дает преимущество в скорости по сравнению с утиной типизацией Clojure, Clojure поддерживает подсказку типов, которая может значительно ускорить код. Возможно, обычный Scala быстрее обычного Clojure, но вам нужно только оптимизировать узкие места. Большая часть времени выполнения программы создается небольшим количеством фактического кода.

Что касается взаимодействия с Java, Scala ближе к Java, но я уверен, что оба языка хорошо взаимодействуют. В книге «Программирование Clojure» Стюарт Хэллоуэй пишет: «[вы можете получить доступ] ко всему, что вы можете получить из кода Java. ».

А поскольку автор Scala Мартин Одерский написал компилятор Java Sun, я думаю, что со стороны Scala тоже ничего не упало. :-)

Вам будет сложно выбрать два языка лучше, хотя мне тоже нравится Ruby. Почему вы беспокоитесь о том, какой из них попробовать? Почему бы не попробовать их обоих? Скорее всего, Scala станет «следующей Java», хотя трудно представить, что Lisp, наконец, станет популярным после того, как не делал этого более 50 лет. Но ясно, что Lisp находится на собственном уникальном уровне абстракции, а Clojure довольно прост, поэтому Scala + Clojure не будет намного сложнее, чем просто (довольно сложный) Scala, и я уверен, что вы будете рады, что сделали Это.

И в этом отношении они взаимодействуют ...

* dalvik (Android JVM) получил JIT-компилятор в версии 2.2 в 2010 году

DigitalRoss
источник
6
Ага. Что ж, спасибо за все идеи. Сначала я был в режиме, в котором я хотел просто выбрать один и запустить его. Но по какой-то причине мне не пришло в голову, что я могу просто использовать оба и заставить их взаимодействовать. Так что, возможно, я выберу оба и прогуляюсь с ними :-)
Райан Делукки, 01
7
И я хотел бы добавить, что у меня есть некоторая «слабость» к LISP, поэтому того факта, что Clojure страдает паретезитом, недостаточно, чтобы меня отпугнуть.
Райан Делукки, 01
8
Не всегда верно, что язык, написанный в JVM, будет работать с максимальной скоростью. Исходный JRuby имел ужасную производительность, потому что это был интерпретатор, скомпилированный для JVM, а не исходный код. Язык тоже может быть виноват. Статически типизированные языки часто легче оптимизировать, чем динамические языки и т. Д.
Билл К.
7
-1 «и Scala, и Clojure являются языками JVM, поэтому они должны иметь одинаковую производительность» не имеет абсолютно никакого смысла. Динамические языки, которые должны оставаться совместимыми со статическими языками, такими как Java, всегда намного медленнее (перегрузка требует огромных затрат,
подсказка
4
@julkiewicz - это просто неправда, что динамические языки всегда намного медленнее. Это зависит от того, сможет ли ваш компилятор должным образом оптимизировать рассматриваемый код. Например, в Clojure вы можете выполнять арифметические операции с примитивами Java, которые точно соответствуют производительности Java. Точно так же вызов метода для объекта Java с указанием типа выполняется так же быстро, как вызов метода объекта Java. Компилятор Clojure по существу создает тот же байт-код, что и javac для эквивалентного кода Java.
mikera 01
32

В нынешней JVM Scala имеет преимущество за счет статической типизации, поскольку JVM поддерживает динамическую типизацию - отражение - медленную. Фактически, одна функция Scala, которая должна быть реализована с помощью тех же методов, структурных типов, часто предостерегается именно по этой причине.

Кроме того, Scala отлично принимает изменяемые объекты, а некоторые алгоритмы просто быстрее реализовать с помощью изменяемости.

Поскольку и Scala, и Java по сути являются языками на основе классов, они легче взаимодействуют. Или, может быть, более плавно. Класс Java - это класс для Scala, а класс Scala - это класс для Java. Проблемы могут возникнуть, когда дело доходит до синглтонов Scala или статических членов Java, особенно когда есть структура, предполагающая, что все будет работать определенным образом.

Поэтому я бы использовал Scala для обеих этих учетных записей. Clojure во многих отношениях лучший язык , и у него, безусловно, есть очень интересные функции, которых нет (пока) в Scala, но вы получаете такие преимущества, работая полностью функционально. Если вы намереваетесь это сделать, то Clojure, скорее всего, лучше. Если вы этого не сделаете, вам, вероятно, следует остаться с Scala.

Дэниел С. Собрал
источник
9
Функции функционального программирования clojure - самая веская причина, по которой я рассматриваю этот язык. Я подхожу к тому моменту, когда: если я что-то не кодирую функционально - зачем мне вообще нужен язык сценариев, встроенный в Java? У меня уже есть Python для выполнения быстрых и грязных задач.
Райан Делукки, 01
«язык сценариев, встроенный в Java». Обоснуйте пожалуйста.
Jus12
@ Даниэль: Извините за путаницу. Я имел в виду комментарий в адрес Райана Делукки. Он говорит, что Scala - это «язык сценариев, встроенный в Java», который я не покупаю. (Если только он не имел в виду Clojure, о котором я понятия не имею).
Jus12
@ Jus12 Я понял, что он использует эти языки в качестве языков сценариев JVM, и, учитывая это, он не видит в них каких-либо преимуществ перед Python, если он не переходит в функциональную среду. Опять же, я не он, поэтому могу только догадываться.
Дэниел С. Собрал,
20

Обратите внимание, что Clojure и Scala - это два совершенно разных типа языков программирования. Clojure - это функциональный язык, подобный Lisp, он не является объектно-ориентированным. Scala - это объектно-ориентированный язык с функциями функционального программирования.

На мой взгляд, особенности и концепции языка (функциональный, объектно-ориентированный, ...) являются гораздо более важными критериями для выбора языка, чем производительность (конкретной реализации этого языка) - хотя я понимаю, что вы не хотите попасть в ловушку языка, для которого нет хорошо работающей реализации.

Я бы выбрал Scala, потому что он объектно-ориентированный, но также позволяет изучать функциональное программирование (если вам это интересно). С другой стороны, если вас не волнует объектно-ориентированный подход и вы хотите изучить «чистое» функциональное программирование, попробуйте Clojure.

Джеспер
источник
9
Очевидно, вы не использовали Clojure. Clojure примерно так же объектно-ориентирован, как и Scala функциональна. Вы можете реализовать интерфейс, расширить класс, объявить частные и статические функции и т. Д. ( Clojure.org/java_interop ).
Ричард Клейтон
28
Эти вещи существуют в Clojure для взаимодействия с Java, но классы и объекты явно не являются основными функциями Clojure. Вы не создаете классы и не разрабатываете свой проект объектно-ориентированным способом, если собираетесь программировать на Clojure.
Джеспер,
>> "чем спектакль". Проблема в следующем: что происходит, когда - в глубине проекта - вы обнаруживаете, что ваша производительность низка - и не из-за всего лишь одного небольшого ее фрагмента (который вы уже планировали преобразовать в java именно по этой причине). Хотя я не собираюсь здесь говорить «не используйте clojure - period ..», должно быть ясно, что закрытие представляет собой больший риск на арене производительности. Существует множество возможностей для кода уровня приложения, для которого это не имеет значения: но также существует множество баз кода с интенсивной структурой / многопоточностью / обработкой, где это было бы помехой.
StephenBoesch
@javadba Идея о том, что clojure плохо подходит для низкоуровневого многопоточного кода, кажется довольно произвольной. Clojure спроектирован таким образом, что ошибки многопоточного программирования очень сложно сделать. Неизменяемые данные и функции STM, которые являются ядром языка clojure, недоступны в ядре Scala, и они значительно снижают вероятность того, что программист случайно вставит условие гонки или тупик в свой код. Конечно, это более ценно, чем несколько миллисекунд времени выполнения, которые вы можете получить от статически типизированного языка, такого как Scala или Java.
nben
«Конечно, это более ценно, чем несколько миллисекунд времени выполнения» .. Это зависит от масштаба данных. несколько мс подходят для нескольких записей. умножить на сотни миллионов ..
StephenBoesch
16
  1. Идиоматическая Scala быстрее, чем идиоматическая Clojure, и останется таковой.
  2. И Scala, и Clojure легко устанавливаются поверх Java. Ни то, ни другое не подходит под это.

Если ваш код критичен ко времени или пространству, придерживайтесь Java. Но это не так, даже если вы так думаете.

Игра Computer Language Benchmark Game не проливает света на истинную стоимость ресурсов Clojure. Никакие структуры данных Clojure не используются. Функциональные абстракции и абстракции последовательностей не появляются.

Clojure может показаться простым. Нет, но выразительно. Он может работать в пять раз медленнее, чем Java, но исходный код в пять раз меньше (YMMV). Для большинства приложений это большая победа. Но для некоторых и для некоторых частей многих других это сокрушительная потеря.

Имея опыт работы с языком Clojure, я считаю, что можно заранее сказать, будет ли ваша проблема четко разделена на часть, которая может быть кратко и адекватно (с точки зрения производительности) выражена в Clojure, и часть, которая требует решения на Java.

  • Вы можете пойти на Scala lite: писать идиомы Java на Scala. Вы получите некоторую краткость, упрощенный для глаз синтаксис и согласованную, хотя и сложную систему типов.
  • Clojure lite не существует: писать идиомы Java на Clojure совершенно бессмысленно. Все, что вы получите, - это медленная Java, которую трудно понять, потому что она пересекает структуру идиом, используемых для ее выражения.

Говорят, что Scala - это правильно сделанная Java . Clojure не похож на Java. Вы можете сказать, что это Лисп, сделанный правильно - смелое, некоторые скажут абсурдное утверждение, - которое может оказаться правдой.

Эскиз
источник
4
Этот ответ проливает свет на истинные различия и сильные / слабые стороны этих двух. Он написан не в стиле апологетов scala- или clojure-, а скорее правдивым.
Стивен Бош
15

Статистические данные, полученные с помощью " Компьютерной языковой тестовой игры ", - это лучшее, что вы, вероятно, найдете.

Они всесторонние, и вы можете сравнивать многие языки. Проблема в том, что они не охватывают Clojure :(

Тем не менее, отправить что угодно довольно просто - все это с открытым исходным кодом.

Статистика действительно говорит, что Scala чертовски быстр.

Билл К
источник
9
Вот так. В 2-25 раз медленнее, чем Java, в 2-30 раз больше памяти и размер кода, как правило, больше, чем у Java. Похоже, это сравнимо с Python, где Scala очень близка к Java. Я бы сказал, что Scala - явный победитель, а Clojure значительно медленнее, если только тест Clojure не был написан плохо.
Bill K
2
Кажется, что эталонный тест теперь охватывает Clojure (примечанию OP год назад). И результаты не радуют. Scala - это то, что нужно.
Мартин
4
Приведенные выше комментарии несколько устарели - по состоянию на середину 2012 года Clojure существенно сократил разрыв, и сейчас он составляет в среднем только 2x Java.
mikera 01
9

Что касается взаимодействия, я не могу говорить о Clojure, но я ожидал бы, что он будет в той же ситуации, что и Scala.

Вызвать Java из Scala тривиально просто.

Вызвать Scala из Java легко, если вы согласовываете внешний API с общими точками между Scala и Java. Например, объект Scala в некотором роде используется как статические методы в Java, но это не одно и то же. Классы Scala могут компилироваться в несколько классов с именами, которые выглядят забавно в Java.

Вам не захочется много смешивать и сочетать. Создание компонента на Scala или Clojure, использующего множество библиотек Java, вполне возможно. Вы, конечно, можете вызывать этот компонент из Java, но вам не нужно пытаться использовать Scala API, предназначенный для использования программами Scala из Java.

SVN утверждает, что «CVS сделан правильно». На мой взгляд, Scala - это правильно сделанная Java.

Кевин Петерсон
источник
1
@ Рон, ха-ха, я думал точно так же.
KoW
2
На самом деле коллекции Clojure мерзкие
Джо Леманн
2

В ноябрьском выпуске PragPub за 2010 год обсуждается совместимость Clojure и Java. Вызов методов Java прост, но расширение классов / интерфейсов Java совершенно иное.

С другой стороны, Scala намного ближе к Java. Совместимость Scala и Java разработана на http://www.codecommit.com/blog/java/interop-between-java-and-scala.

Вызов кода Java и расширение классов / интерфейсов Java работает так же, как вызов кода Scala. Некоторые болевые точки могут быть крайними случаями работы с дженериками Java, потому что система типов в Scala намного сильнее, чем в Java. Для создания геттеров и сеттеров в соответствии с соглашением Java Bean требуется аннотация .

Вызов Scala из Java в большинстве случаев является простым, но, например, сопутствующие объекты Scala требуют знания того, как они компилируются в байт-код. Кроме того, использование трейтов с неабстрактными методами из Java должно быть сложным, а для вызова методов со специальными символами потребуется знать, как они закодированы в байт-коде.

Эско Луонтола
источник
1

Сейчас (по состоянию на май 2010 г.) стоит заглянуть в последнюю ветку Clojure 1.2 - она ​​включает в себя много дополнительной поддержки примитивных типов и статической типизации (с помощью различных подсказок типов и протоколов).

Насколько я понимаю, вы можете использовать эти функции, когда вам это нужно, чтобы получить скорость, эквивалентную написанию точно такого же кода на чистой Java.

Микера
источник
2
И в то же время @specializedтехника в готовящейся к выпуску Scala 2.8 вносит аналогичное улучшение в библиотеки Scala. И как языковая возможность, она доступна для всего кода, а не только для стандартной библиотеки.
Рэндалл Шульц