Zu Leistung und Java-Interoperabilität: Clojure vs. Scala

82

Ich habe bereits verschiedene Berichte über Clojure vs. Scala gelesen und obwohl mir klar ist, dass beide ihren Platz haben. Es gibt einige Überlegungen, zu denen ich beim Vergleich von Clojure und Scala keine vollständige Erklärung erhalten habe:

1.) Welche der beiden Sprachen ist im Allgemeinen schneller ? Mir ist klar, dass dies von Sprachmerkmal zu Sprachmerkmal unterschiedlich sein wird, aber eine allgemeine Bewertung der Leistung wäre hilfreich. Zum Beispiel: Ich weiß, dass Python-Wörterbücher sehr schnell sind. Insgesamt ist es jedoch eine viel langsamere Sprache als Java. Ich möchte nicht mit Clojure gehen und später auf dieses Problem stoßen.

2.) Wie ist die Interoperabilität mit Java? Alles, was ich bisher gelesen habe, ist, dass Scala native Sammlungstypen hat, die die Integration in eine große Java-Codebasis etwas umständlich machen, während Clojure eine einfache Iterable / Iterator-zentrierte Methode zur Interaktion mit Java-Klassen verfolgt. Noch mehr Gedanken / Details dazu?

Wenn es zwischen Clojure und Scala eng genug ist, könnte ich letztendlich beide ausprobieren. Eine Sache bei Clojure ist, dass die Sprache sehr einfach zu sein scheint . Andererseits hat Scala ein sehr flexibles Typensystem. Aber ich weiß, dass Scala schnell ist (basierend auf mehreren persönlichen Konten). Also, wenn Clojure deutlich langsamer ist: Ich würde es lieber früher als später wissen.

Ryan Delucchi
quelle
1
Mit Clojure 1.2 kann Clojure Java ohne Overhead aufrufen. Schauen Sie sich assembla.com/wiki/show/clojure/Datatypes und assembla.com/wiki/show/clojure/New_new an . Dies geschieht, weil Clojure in der Nähe von Java sein möchte, aber in Clojure implementiert ist.
Nickik

Antworten:

73

Ich denke, jede Sprache wird schnell genug für Sie sein. Beim Vergleich von Python und Java erscheint es etwas unvernünftig, die Sprache für den Geschwindigkeitsunterschied verantwortlich zu machen. Java ist JIT kompiliert (außer auf Mobilgeräten *), während Python interpretiert wird. Nur weil beide einen Bytecode verwenden, bedeutet dies nicht, dass die Implementierungen auch nur eine entfernt vergleichbare Leistung aufweisen. Aber sowohl Scala als auch Clojure sind JVM-Sprachen, daher sollten sie eine ähnliche Leistung haben.

Scala hat einige Implementierungsvorteile gegenüber Clojure und ich würde eine etwas höhere Leistung erwarten. Obwohl Scalas statische Typisierung normalerweise zu einem Geschwindigkeitsvorteil gegenüber Clojures Ententypisierung führen würde, tut Clojure dies unterstützt Typhinweise, die den Code erheblich beschleunigen können. Möglicherweise ist gewöhnliche Scala schneller als gewöhnliche Clojure, aber Sie müssen nur die Engpässe optimieren. Der größte Teil der Laufzeit eines Programms wird durch einen kleinen Teil des tatsächlichen Codes generiert.

In Bezug auf Interop mit Java ist Scala näher an Java, aber ich bin sicher, dass beide Sprachen gut zusammenarbeiten. In Programming Clojure schreibt Stuart Halloway: "[Sie können auf alles zugreifen], was Sie mit Java-Code erreichen können. "

Und da Scala Autor Martin Odersky schrieb Suns Java - Compiler, glaube ich irgendwie keine Kugeln auf der Scala Seite fallen gelassen wurden, auch nicht . :-)

Es würde Ihnen schwer fallen, zwei bessere Sprachen auszuwählen, obwohl ich Ruby auch mag. Warum machst du dir Sorgen, welches du versuchen sollst? Warum probieren Sie nicht beide? Scala ist eher "das nächste Java", während es schwer vorstellbar ist, dass Lisp nach über 50 Jahren nicht mehr startet. Aber es ist klar, dass Lisp auf seiner eigenen einzigartigen Abstraktionsebene liegt und Clojure ziemlich einfach ist, so dass Scala + Clojure nicht viel schwieriger sein wird als nur (die ziemlich komplexe) Scala, und ich bin sicher, Sie werden es nicht bereuen es.

Und im Übrigen arbeiten sie zusammen ...

* dalvik (android's JVM) hat 2010 einen JIT-Compiler in der Version 2.2 erhalten

DigitalRoss
quelle
6
Huh. Vielen Dank für all die Erkenntnisse. Zuerst war ich in dem Modus, in dem ich nur einen auswählen und damit rennen wollte. Aber aus irgendeinem Grund kam mir nicht der Gedanke, dass ich einfach beide verwenden und sie zusammenarbeiten lassen könnte. Also, vielleicht werde ich beide auswählen und einen schnellen Spaziergang mit ihnen machen :-)
Ryan Delucchi
7
Und ich möchte hinzufügen, dass ich eine gewisse "Schwäche" für LISP habe, sodass die Tatsache, dass Clojure an Parethesitis leidet, nicht ausreicht, um mich abzuschrecken.
Ryan Delucchi
8
Es ist nicht immer wahr, dass eine in der JVM geschriebene Sprache mit Höchstgeschwindigkeit funktioniert. Der ursprüngliche JRuby hatte eine miserable Leistung, da es sich um einen Interpreter handelte, der für die JVM kompiliert wurde, nicht für den Quellcode. Auch die Sprache kann schuld sein. Statisch typisierte Sprachen sind oft einfacher zu optimieren als dynamische Sprachen usw.
Bill K
7
-1 "Sowohl Scala als auch Clojure sind JVM-Sprachen, daher sollten sie eine ähnliche Leistung haben" macht absolut keinen Sinn. Dynamische Sprachen, die mit statischen Sprachen wie Java interoperabel bleiben müssen, sind immer viel langsamer (Überladung ist mit enormen Kosten verbunden,
Tipphinweise
4
@julkiewicz - es ist einfach nicht wahr, dass dynamische Sprachen immer viel langsamer sind. Dies hängt davon ab, ob Ihr Compiler den betreffenden Code ordnungsgemäß optimieren kann. In Clojure können Sie beispielsweise mit Java-Grundelementen rechnen, die genau der Java-Leistung entsprechen. Ebenso ist das Aufrufen einer Methode für ein vom Typ angedeutetes Java-Objekt so schnell wie das Aufrufen einer Java-Objektmethode. Der Clojure-Compiler erzeugt im Wesentlichen den gleichen Bytecode wie javac für äquivalenten Java-Code.
Mikera
32

Mit der gegenwärtigen JVM hat Scala einen Vorteil aufgrund der statischen Typisierung, da die JVM-Unterstützung für die dynamische Typisierung - Reflexion - langsam ist. Tatsächlich wird aus genau diesem Grund häufig vor einer Scala-Funktion gewarnt, die mit denselben Techniken, Strukturtypen, implementiert werden muss.

Außerdem akzeptiert Scala veränderbare Objekte einwandfrei, und einige Algorithmen lassen sich mit Veränderlichkeit nur schneller implementieren.

Da sowohl Scala als auch Java im Wesentlichen klassenbasierte Sprachen sind, können sie leichter zusammenarbeiten. Oder vielleicht nahtloser. Eine Java-Klasse ist eine Klasse für Scala, und eine Scala-Klasse ist eine Klasse für Java. Probleme können auftreten, wenn es um Scalas Singletons oder Javas statische Mitglieder geht, insbesondere wenn es ein Framework gibt, bei dem erwartet wird, dass die Dinge auf eine bestimmte Weise funktionieren.

Also würde ich mit Scala auf beiden gehen diesen Konten. Clojure ist in vielerlei Hinsicht eine bessere Sprache , und es hat sicherlich sehr interessante Funktionen, die Scala (bisher) nicht bietet, aber Sie profitieren von solchen Vorteilen, wenn Sie voll funktionsfähig sind. Wenn Sie das vorhaben, ist Clojure sehr wahrscheinlich besser. Wenn Sie dies nicht tun, sollten Sie wahrscheinlich bei Scala bleiben.

Daniel C. Sobral
quelle
9
Die funktionalen Programmierfunktionen von clojure sind der überzeugendste Grund, warum ich diese Sprache in Betracht ziehe. Ich komme an den Punkt, an dem: Wenn ich etwas nicht funktional codiere - warum beschäftige ich mich dann überhaupt mit einer in Java eingebetteten Skriptsprache? Ich habe bereits Python an meiner Seite, um schnelle und schmutzige Aufgaben zu erledigen.
Ryan Delucchi
9
Dann geh mit Clojure.
Daniel C. Sobral
"In Java eingebettete Skriptsprache". Bitte begründen Sie.
Jus12
@ Daniel: Entschuldigung für die Verwirrung. Ich meinte den Kommentar zu Ryan Delucchi. Er sagt, dass Scala eine "in Java eingebettete Skriptsprache" ist, die ich nicht kaufe. (Es sei denn, er meinte Clojure, von dem ich keine Ahnung habe).
Jus12
@ Jus12 nahm ich es bedeuten , dass er mit dieser Sprachen als JVM Skriptsprachen, und, da sieht er keinen Vorteil in ihnen über Python sehen , es sei denn er funktionelle geht. Andererseits bin ich nicht er, also kann ich nur raten.
Daniel C. Sobral
20

Beachten Sie, dass Clojure und Scala zwei völlig unterschiedliche Arten von Programmiersprachen sind - Clojure ist eine funktionale Lisp-ähnliche Sprache, die nicht objektorientiert ist. Scala ist eine objektorientierte Sprache mit funktionalen Programmierfunktionen.

Meiner Meinung nach sind die Merkmale und Konzepte einer Sprache (funktional, OO, ...) viel wichtigere Kriterien für die Auswahl einer Sprache als die Leistung (einer bestimmten Implementierung dieser Sprache) - obwohl ich verstehe, dass Sie dies nicht tun Ich möchte in einer Sprache gefangen sein, für die keine leistungsfähige Implementierung verfügbar ist.

Ich würde mich für Scala entscheiden, weil es objektorientiert ist, aber auch das Erlernen der funktionalen Programmierung ermöglicht (wenn Sie daran interessiert sind). Auf der anderen Seite, wenn Sie sich nicht für OO interessieren und "reine" funktionale Programmierung lernen möchten, versuchen Sie es mit Clojure.

Jesper
quelle
9
Offensichtlich haben Sie Clojure nicht verwendet. Clojure ist ungefähr so ​​objektorientiert wie Scala funktional ist. Sie können eine Schnittstelle implementieren, eine Klasse erweitern, private und statische Funktionen deklarieren usw. ( clojure.org/java_interop ).
Richard Clayton
28
Diese Dinge existieren in Clojure für die Interoperabilität mit Java, aber Klassen und Objekte sind eindeutig keine Hauptmerkmale von Clojure. Sie erstellen keine Klassen und entwerfen Ihr Projekt nicht auf OO-Weise, wenn Sie in Clojure programmieren möchten.
Jesper
>> "als die Leistung". Das Problem ist: Was passiert, wenn Sie - tief in einem Projekt - feststellen, dass Ihre Leistung schlecht ist - und nicht nur aufgrund eines kleinen Teils davon (den Sie bereits aus diesem Grund in Java konvertieren wollten). Obwohl ich hier nicht die Absicht habe zu sagen "benutze keine Clojure - Periode ...", sollte klar sein, dass Clojure ein größeres Risiko im Leistungsbereich darstellt. Es gibt viele Möglichkeiten für Code auf Anwendungsebene, für die dies keine Rolle spielt: aber auch viele Framework- / Multithreading- / Verarbeitungs-intensive Codebasen, bei denen dies eine Haftung darstellen würde.
Javadba
@javadba Die Idee, dass Clojure schlecht für Multithread-Code auf niedriger Ebene ist, scheint ziemlich willkürlich. Clojure ist so konzipiert, dass Multithread-Programmierfehler sehr schwer zu machen sind. Die unveränderlichen Daten und STM Funktionen , die Kern der clojure Sprache sind etwas nicht im Kern Scala, und sie machen es viel weniger wahrscheinlich , dass ein Programmierer versehentlich eine Race - Bedingung oder Deadlock in ihren Code einfügt. Dies ist sicherlich wertvoller als die wenigen ms Laufzeit, die Sie möglicherweise von einer statisch typisierten Sprache wie Scala oder Java erhalten.
Nben
"Sicherlich ist dies wertvoller als die wenigen ms Laufzeit". Das hängt von der Größe der Daten ab. Ein paar ms sind gut für ein paar Datensätze. multiplizieren Sie mit Hunderten von Millionen ..
Javadba
16
  1. Idiomatische Scala ist schneller als idiomatische Clojure und wird es auch bleiben.
  2. Sowohl Scala als auch Clojure sitzen problemlos auf Java. Keiner sitzt gut darunter.

Wenn Ihr Code durchgehend zeit- oder raumkritisch ist, bleiben Sie bei Java. Aber es ist nicht so, auch wenn du denkst, dass es so ist.

Das Computersprachen-Benchmark-Spiel gibt wenig Aufschluss über die tatsächlichen Ressourcenkosten von Clojure. Es werden keine Clojure-Datenstrukturen verwendet. Funktions- und Sequenzabstraktionen werden nicht angezeigt.

Clojure mag einfach erscheinen. Es ist nicht, aber es ist ausdrucksstark. Es läuft möglicherweise fünfmal langsamer als Java, aber die Quelle ist fünfmal kleiner (YMMV). Für die meisten Anwendungen ist dies ein großer Gewinn. Aber für einige und für einige Teile von vielen anderen ist es ein verheerender Verlust.

Aufgrund der Erfahrung mit der Clojure-Sprache ist es meines Erachtens möglich, im Voraus zu sagen, ob Ihr Problem sauber in einen Teil zerfällt, der in Clojure kurz und angemessen (in Bezug auf die Leistung) ausgedrückt werden kann, und einen Teil, der in Java ausgeführt werden muss.

  • Sie können sich für Scala Lite entscheiden: Schreiben von Java-Redewendungen in Scala. Sie erhalten eine gewisse Kürze, eine Syntax, die das Auge schont, und ein kohärentes, wenn auch komplexes Typensystem.
  • Clojure lite gibt es nicht: Das Schreiben von Java-Redewendungen in Clojure ist völlig sinnlos. Alles, was Sie erhalten, ist langsames Java, das schwer zu verstehen ist, da es die Redewendungen durchschneidet, mit denen es ausgedrückt wird.

Scala soll Java richtig gemacht haben . Clojure ist nichts wie Java. Man könnte sagen, dass es Lisp ist, der richtig gemacht wurde - eine kühne, manche würden sagen absurde Behauptung -, die sich als wahr herausstellen könnte.

Miniaturansicht
quelle
4
Diese Antwort wirft ein gutes Licht auf die wahren Unterschiede und Stärken / Schwächen der beiden. Es ist weder skala- noch clojure-apologisch geschrieben, sondern wahrheitsgemäß.
Javadba
15

Die Statistiken des " Computer Language Benchmark Game " sind ungefähr die besten, die Sie wahrscheinlich finden werden.

Sie sind ausführlich und Sie können viele Sprachen vergleichen. Das Problem ist, dass sie Clojure nicht abdecken :(

Das heißt, es ist ziemlich einfach, etwas einzureichen - es ist alles Open Source.

Die Statistiken sagen, dass Scala verdammt schnell ist.

Bill K.
quelle
9
Los geht's. 2-25x langsamer als Java, 2-30x mehr Speicher und Code sind im Allgemeinen größer als Java. Sieht aus wie es mit Python vergleichbar ist, wo Scala Java sehr nahe kommt. Ich würde sagen, Scala ist ein ziemlich klarer Gewinner und Clojure ist deutlich langsamer - es sei denn, der Clojure-Test wurde schlecht geschrieben.
Bill K
2
Es scheint, dass der Benchmark jetzt Clojure abdeckt (die Bemerkung von OP ist ein Jahr alt). Und die Ergebnisse sind nicht ermutigend. Scala ist der richtige Weg.
Martin
4
Die obigen Kommentare sind etwas veraltet - Ab Mitte 2012 hat Clojure die Lücke erheblich geschlossen, jetzt sind es durchschnittlich nur noch etwa 2x Java.
Mikera
9

In Bezug auf die Interoperabilität kann ich nicht für Clojure sprechen, aber ich würde erwarten, dass es sich in einer ähnlichen Situation wie bei Scala befindet.

Es ist trivial einfach, Java von Scala aus aufzurufen.

Es ist einfach, Scala von Java aus aufzurufen, solange Sie Ihre externe API an die gemeinsamen Punkte zwischen Scala und Java anpassen. Beispielsweise wird ein Scala-Objekt in gewisser Weise wie statische Methoden in Java verwendet, aber es ist nicht dasselbe. Scala-Klassen können zu einer Reihe von Klassen mit Namen kompiliert werden, die in Java lustig aussehen.

Sie werden nicht viel mischen und kombinieren wollen. Das Erstellen einer Komponente in Scala oder Clojure, die viele Java-Bibliotheken verwendet, ist sehr machbar. Sie können diese Komponente natürlich von Java aus aufrufen, aber Sie möchten nicht versuchen, eine Scala-API zu verwenden, die von Scala-Programmen aus Java verwendet werden soll.

SVN behauptet, "CVS richtig gemacht" zu sein. Aus meiner Sicht ist Scala Java richtig gemacht.

Kevin Peterson
quelle
19
so clojure ist git?
Ron
1
@ Ron haha, ich dachte genau das gleiche.
KoW
2
Eigentlich sind die Sammlungen von Clojure git-ish
Joe Lehmann
2

In der November 2010-Ausgabe von PragPub wird die Interoperabilität zwischen Clojure und Java erörtert. Das Aufrufen von Java-Methoden ist unkompliziert, das Erweitern von Java-Klassen / -Schnittstellen ist jedoch ganz anders.

Scala hingegen ist Java viel näher. Die Interoperabilität zwischen Scala und Java wird unter http://www.codecommit.com/blog/java/interop-between-java-and-scala erläutert

Das Aufrufen von Java-Code und das Erweitern von Java-Klassen / -Schnittstellen funktioniert genauso wie das Aufrufen von Scala-Code. Einige Schwachstellen könnten einige Randfälle beim Umgang mit Javas Generika sein, da das Typensystem von Scala viel stärker ist als das von Java. Das Erstellen von Gettern und Setzern gemäß der Java Bean-Konvention erfordert eine Anmerkung .

Das Aufrufen von Scala von Java aus ist meistens unkompliziert, aber zum Beispiel müssen die Begleitobjekte von Scala wissen, wie sie zu Bytecode kompiliert werden. Auch die Verwendung von Merkmalen mit nicht abstrakten Methoden aus Java sollte kompliziert sein, und das Aufrufen von Methoden mit Sonderzeichen würde das Wissen erfordern, wie sie im Bytecode codiert sind.

Esko Luontola
quelle
1

Es lohnt sich jetzt (ab Mai 2010), den neuesten 1.2-Zweig von Clojure zu besuchen - dies beinhaltet eine Menge zusätzlicher Unterstützung für primitive Typen und statische Typisierung (durch verschiedene Typhinweise und Protokolle).

Meines Wissens nach können Sie diese Funktionen verwenden, wenn Sie sie benötigen, um eine Geschwindigkeit zu erzielen, die dem Schreiben genau des gleichen Codes in reinem Java entspricht.

mikera
quelle
2
Gleichzeitig @specializedbringt die Technik in der kommenden Scala 2.8 eine analoge Verbesserung für die Scala-Bibliotheken. Und als Sprachfunktion steht es allen Codes zur Verfügung, nicht nur der Standardbibliothek.
Randall Schulz