Verwenden Sie Clojure anstelle von Python aus Gründen der Skalierbarkeit (Multi-Core). Gute Idee? [geschlossen]

8

Nachdem ich http://clojure.org/rationale und andere Leistungsvergleiche zwischen Clojure und vielen Sprachen gelesen hatte , begann ich zu denken, dass ich, abgesehen von der Benutzerfreundlichkeit, nicht mehr in Python, sondern in Clojure programmieren sollte. Eigentlich fühlte ich mich unverantwortlich, weil ich Clojure nicht gelernt hatte, weil ich die Vorteile sah.

Macht das Sinn? Kann ich nicht alle Kerne mit einer zwingenderen Sprache wie Python wirklich effizient nutzen als mit einem Lisp-Dialekt oder einer anderen funktionalen Sprache? Es scheint, dass alle Vorteile aus der Verwendung unveränderlicher Daten resultieren. Kann ich nicht genau das in Python tun und alle Vorteile haben?

Ich habe einmal angefangen, Common Lisp zu lernen, fast alle Übungen aus einem Buch zu lesen und zu machen, das ich aus meiner Universitätsbibliothek ausgeliehen habe (ich fand es ziemlich gut, obwohl es bei Amazon wenig beliebt ist). Aber nach einer Weile hatte ich zu viel Mühe, einige einfache Dinge zu tun. Ich denke, es gibt Dinge, die ihrer Natur nach zwingender sind und die es schwierig machen, diese Dinge auf funktionale Weise zu modellieren.

Ist Python so leistungsfähig wie Clojure, um Anwendungen zu erstellen, die diese neue Multi-Core-Zukunft nutzen?

Beachten Sie, dass ich nicht denke, dass die Verwendung von Semaphoren, Sperrmechanismen oder anderen ähnlichen Parallelitätsmechanismen eine gute Alternative zu Clojures 'automatischer' Parallelisierung darstellt.

Julio Rodrigues
quelle
5
Basierend auf dem, was Sie zu erreichen scheinen, sollten Sie sich auch wirklich mit erlang befassen .
Jerry Coffin
2
Es ist noch nicht hier und wird vielleicht nie gut funktionieren, aber die STM-Pläne der PyPy- Leute ( naja , meistens einer: Armin Rigo) klingen cool und hängen greifbar mit dieser Frage zusammen.

Antworten:

4

Kann ich nicht alle Kerne mit einer zwingenden Sprache wie Python wirklich effizient nutzen als mit einem Lisp-Dialekt oder einer anderen funktionalen Sprache?

Das kannst du definitiv . Abhängig von der Art des Problems (z. B. klar trennbare Teile einer großen Rechenaufgabe parallel verarbeiten) kann dies sogar recht einfach sein. Ich denke, der größte Teil der Parallelität in der Welt erfolgt immer noch direkt in imperativen Sprachen, obwohl sich das Paradigma in Richtung funktionaler Lösungen verschiebt.

Python ist jedoch nicht gerade für seine Parallelitätsfunktionen bekannt. Ein Beispiel für eine etablierte imperative Sprache mit hervorragender Unterstützung für Parallelität ist Java.

Es scheint, dass alle Vorteile aus der Verwendung unveränderlicher Daten resultieren. Kann ich nicht genau das in Python tun und alle Vorteile haben?

Der Trick bei unveränderlichen Daten besteht darin, dass Sie, wenn Sie dies mit den traditionellen, einfachen Datenstrukturen wie Arrays tun, massiv kopieren und Speicherbereinigungen durchführen, was die Leistung beeinträchtigt. Stattdessen möchten Sie effektiv unveränderliche Daten, die mit verschiedenen persistenten Datenstrukturen implementiert werden können , wie dies in Clojure unter der Haube der Fall ist. Solche Strukturen könnten in so ziemlich jeder Sprache als Bibliotheken erstellt werden, aber eine direkte Sprachunterstützung ist natürlich immer besser.

Joonas Pulakka
quelle
8

Python ist extrem schlecht für Anwendungen, die mehrere Threads benötigen, aber es wird durch einen Mangel an verfügbaren virtuellen Maschinen verursacht, nicht an der Sprache selbst. Pythons Generatoren wären wirklich gute Kandidaten für eine implizite Parallelisierung. Das Problem ist, dass die Standardimplementierung CPython nur Python-Code auf einer CPU ausführen kann. Nur Aufrufe in nativen Bibliotheken können parallel ausgeführt werden. Die PyPy-Laufzeit plant, das Problem zu beheben, ist jedoch noch nicht vorhanden. Die Implementierungen von Jython und IronPython unterliegen zwar nicht den Einschränkungen, sind jedoch eher unvollständig (sie verfügen nicht über einen Großteil der Standardbibliothek, Sie müssen jedoch die Standardbibliothek verwenden der Hosting-Umgebung in ihnen).

Es gibt jedoch viele andere Sprachen, die parallel entworfen und implementiert wurden. Natürlich ist Parallelität in funktionalen Sprachen viel einfacher, weshalb alle Sprachen mit guter Parallelitätsunterstützung entweder funktional sind oder eine starke Unterstützung für funktionale Programmierung haben. Ich kann mir vorstellen:

  • Haskell , die am häufigsten verwendete reine, nicht strenge Funktionssprache. Aufgrund seiner reinen, nicht strengen Natur kann der Compiler einige Dinge implizit parallelisieren.
  • Erlang ist eine streng funktionale Sprache, die speziell für die Implementierung robuster paralleler Server entwickelt wurde und eine integrierte Unterstützung für die Verteilung an Cluster bietet.
  • Clojure natürlich. Wie andere Lisps ist es für die funktionale Programmierung konzipiert, unterstützt aber auch die imperative Programmierung.
  • Go ist eine neue kompilierte prozedurale Sprache, die für die Parallelität entwickelt wurde, obwohl weder die Laufzeit noch die Sprache selbst noch sehr ausgereift sind.
  • Rust ist eine neue kompilierte prozedurale Sprache, die für Parallelität, geringen Overhead und statische Überprüfung des Speichers und der Parallelitätssicherheit entwickelt wurde. Auch noch nicht sehr ausgereift.
Jan Hudec
quelle
Go hatte gerade die Version 1.0 nach ungefähr zwei Jahren Open-Source-Entwicklung.
Sonia
1
Und Python hat das Multiprocessing-Paket.
Sonia
Ich wusste wirklich nicht, dass Haskell schnell sein kann (schneller als Python). Ich habe es in meinem ersten Programmierkurs 'gelernt', ich muss es auf jeden Fall wieder sehen.
Julio Rodrigues
1
@Vandell: Haskell ist eine statisch typisierte kompilierte Sprache, daher ist sie voraussichtlich schneller. Laut The Computer Language Benchmarks Game ist Haskell in etwa mit Java und Mono vergleichbar.
Jan Hudec
@Sonia: ... was ich nicht sehr ausgereift nenne. Normalerweise dauert es 10 oder mehr Jahre, bis die Sprachspezifikation festgelegt ist. Ich erwarte zumindest, dass Go Java und C # folgt und eines Tages Generika erhält.
Jan Hudec
2

Die Jungs hier haben wirklich hervorragende Antworten gegeben.

Die gleichzeitige Programmierung ist normalerweise aufgrund des "Freigabestatus" schwierig. Funktionale Programmierung ist vielleicht nicht die ultimative Antwort, aber sie macht es sicher machbar, ohne dass Sie Ihre Haare verlieren.

Clojure ist sicher eine praktikable Option, aber selbst mit seinen hervorragenden Parallelitätstools müssen Sie möglicherweise etwas anderes erstellen. Überprüfen Sie Prismatic für ein Beispiel:

Unsere Wahl für die Backend-Sprache ist Clojure in der JVM. Es gibt andere großartige funktionale Sprachen in der JVM, wie Scala, aber was uns an Clojure gefällt, ist, dass es einen kleinen, einfachen Kern hat, der sich auf die Verarbeitung von Daten konzentriert, die in seinen hervorragenden persistenten Datenstrukturen (oder ihren veränderlichen java.util-Äquivalenten) dargestellt werden. wenn es nötig ist). Während wir den Kern von Clojure stark nutzen, verwenden wir nicht seine Parallelitätsprimitive (Atome, Refs, STM usw.), da eine Funktion wie pmap nicht genügend fein abgestimmte Steuerung für unsere Anforderungen hat. Wir entscheiden uns stattdessen dafür, unsere eigenen Parallelitätsabstraktionen in Clojure auf dem herausragenden Paket java.util.concurrent aufzubauen.

Wenn Sie wirklich wild werden möchten, überprüfen Sie auch Julia Programming Language .

Julia legt dem Benutzer keinen bestimmten Parallelitätsstil auf. Stattdessen bietet es eine Reihe wichtiger Bausteine ​​für die verteilte Berechnung, sodass es flexibel genug ist, um eine Reihe von Parallelitätsstilen zu unterstützen, und es Benutzern ermöglicht, weitere hinzuzufügen.

Chiron
quelle
2

Zusätzlich zu dem, was Jan Hudec geschrieben hat, möchte ich Scala erwähnen , die neben einem funktionalen Programmierstil auch einen imperativen / objektorientierten Programmierstil unterstützt.

Scala bietet Parallelität durch Schauspieler (auch von Erlang verwendet).

Beachten Sie, dass ich nicht der Meinung bin, dass die Verwendung von Semaphoren, Sperrmechanismen oder anderen ähnlichen Parallelitätsmechanismen eine gute Alternative zur automatischen Clojure-Parallelisierung darstellt.

Akteure sind eine objektorientierte Methode zum Abstrahieren von den zugrunde liegenden Threads / Prozessen: Grundsätzlich sehen Sie nur Objekte, die gleichzeitig ausgeführt werden und Nachrichten aneinander senden. Wenn Sie also eine objektorientierte Methode zur Implementierung von Parallelität wünschen, würde ich mir auch Sprachen (oder Frameworks) ansehen, die das Akteurmodell unterstützen.

Sie können einige Links auf Wikipedia finden , für Python gibt es zB Pykka .

Giorgio
quelle