[Scala]Geschwindigkeitgewinn, Multithreading in Scala besser als in anderen Sprachen?

Zeboo

Lt. Commander
Registriert
Juli 2008
Beiträge
1.562
Hallo,

heute mal kurz in eine Vorlesung mitbekommen, das Scala sehr optimiert sei und man extrem an Speed gegenüber andere Anwendungen rausholen kann. Parallelprogrammierung/Multithreading oder sowas in der Richtung.

Es wurde erwähnt, das Twitter zum Beispiel von Ruby auf Scala umgestiegen ist, WEIL die extrem hohe Belastungen hatten und WEIL man mit Scala genau sowas sehr schön behandeln kann. Sprachen wir Ruby, Python etc. könnten dagegen sowas nicht. Muss anscheinend stimmen :) , twitter setzt ja verstärkt auf Scala.

Also ist da was dran? Verstehe dann aber nicht genau wie das funktioniert. Wo sehe ich denn Beispiele die zeigen was Scala bezüglich Geschwindigkeit etc besser kann wie andere Sprachen? Wie würde die Programmierung zum Beispiel aussehen. Ich meine, in Java können wir ja auch Threadin anwenden.

PS: Mods wann gibt es endlich den Präfix "Scala" in dem Prog Forum hier? ;) Ich meine wenn sogar Python drinne ist... *hust*

Gruß
 
Zu Python und Ruby kann ich dir folgendes sagen. Beide Sprachen besitzen einen sogenannten GIL (Global Interpreter Lock), der bewirkt, daß innerhalb eines Python oder Ruby-Prozesses immer nur ein Interpreter-Thread zur selben Zeit aktiv sein kann. Das bedeutet natürlich, daß du auf Multi-Core-Maschinen keinen Performancegewinn durch Multithreading erzielen kannst. Ich vermute mal, daß Scala diese Einschränkung nicht hat.


http://en.wikipedia.org/wiki/Global_Interpreter_Lock
 
Zuletzt bearbeitet: (Wiki-Link)
antred schrieb:
Zu Python und Ruby kann ich dir folgendes sagen. Beide Sprachen besitzen einen sogenannten GIL (Global Interpreter Lock), der bewirkt, daß innerhalb eines Python oder Ruby-Prozesses immer nur ein Interpreter-Thread zur selben Zeit aktiv sein kann. Das bedeutet natürlich, daß du auf Multi-Core-Maschinen keinen Performancegewinn durch Multithreading erzielen kannst. Ich vermute mal, daß Scala diese Einschränkung nicht hat.


http://en.wikipedia.org/wiki/Global_Interpreter_Lock

Ah okey danke, das ist sehr interessant. Aber dann mal so eine andere Frage: Ruby und Python sind jetzt keine Steinzeitsprachen. Moderne Sprachen müssten alle sowas können, wie kann es sein dass es dort so einfach weggelassen wurde? Bzw. das dort so eine GIL gibt?

Und dann noch natürlich, im vergleich zu Java etc. kann dort Scala auch durch Geschwindigkeit punkten?
 
Der große Vorteil von Scala ist, dass in Funktionen und Kompositionen gedacht wird. In Scala hast du unveränderliche Objekte und brauchst kein synchronized. Es gibt keine Seiteneffekte wegen der funktionalen Programmierung. Daher lässt sich durch funktionale Programmierung die Berechnung sehr gut auf viele Prozessoren verteilen, ohne dass es zu Änderungen kommen kann. Da die Zukunft nun mal Multicores sind, wird die Zukunft den funktionalen Sprachen bzw. hybriden gehören.


PS: James Gosling (Java-Vater) sagt, dass er heute anstelle von Java auf Scala setzen würde.
 
Zuletzt bearbeitet:
Also ich als Scala-Entwickler poste hier mal meine Sicht darauf:

Scala ist langsamer als Java. Ja es ist die gleiche Sache wie von Assembler nach C++ nach Java nach Scala, umso mehr Sprachfeatures eingebaut werden, die eine CPU nicht nativ unterstützt wird es langsamer. Aber bitte versteht mich nicht falsch, ich will nicht sagen, dass Scala langsam ist sondern es eben per Design sein muss, da es Features emuliert, die Java nativ nicht hat, i.R. bewegt sich dies aber in sehr geringem Rahmen.

Der große Vorteil von Scala liegt in dessen Multithreading Modell:
Statt wie in Java (und C++) auf Threads, Locks und Memory Barriers zu setzen um parallelen Code zu schreiben, was wirklich schwierig ist, wer von euch kennt das Java Memory Modell (;))?
Scala setzt dagegen auf ein so genanntes Aktoren-Modell (Actors), statt auf Objekte aus verschiedenen Threads zuzugreifen und jeweils die Objekte locken zu müssen, werden nur noch Nachrichten geschickt, dass das Objekt doch etwas tun soll und einem eine Nachricht mit dem Ergebnis zurückschicken soll.
Statt also einem rein prozeduralen Methoden-Aufruf mit Locking usw. wird auf ein komplett asynchrones Modell gesetzt, dabei wird sehr intelligent "getrickst", so dass dies höllisch effizient:
Schickt man von einem Aktor eine Nachricht an einen Aktor, dann kann es sein, dass der andere Aktor nicht von einem anderen Thread gesteuert wird, sondern vom aktuellen, man also fast doch einen prozeduralen Aufruf hat, sehr genial.
Unter der Haube kümmert Scala sich dann selbst die Aktoren auf Threads zu verteilen, dass ein Aktor nur eine Nachricht zugleich verarbeitet usw.
Milterweile ist es sogar so, dass das base Aktor-Framework für Scala nicht von Scala kommt sondern ein OpenSource-Projekt ist: Akka

Scala punktet eben dadurch, dass Programmierung für mehrere Prozessoren oder Kerne so einfach wie noch nie ist, und man sich dabei überhaupt keine Gedanken machen muss. Manuell mit Threads zu bauen ist zwar an einigen Ecken effektiver und schneller, aber es geht ja gar nicht darum, die effizienteste Sprache zu sein, sondern die Sprache die am effizientesten mit geringem Aufwand ist, und das erreicht Scala mehr als gut.

Die große Errungenschaft von Scala ist das Aktorenmodell, welches schon bei Erlang gezeigt hat, dass es hoch skalierbar ist.
Um das Aktorenmodell jedoch voll zu verstehen, musst du ein wenig googlen. Eventuell steht auch einiges nützliches in dem frei verfügbaren Buch Programming Scala, das kann ich dir jedoch nicht sagen, da ich nur das Buch direkt vom Scala-Erfinder Odersky habe.
 
Zuletzt bearbeitet:
Hmm... Ich wollte mich zwar seit längerem mit Scala beschäftigen, aber ein gedanke hat mich bis dato immer abgehalten: Scala kann nicht mehr können als Java, da es letztendlich nur Java ist.
Ergo sind beide Sprachen gleich mächtig und sollte mit unterschieden im Overhead auch gleich schnell sein...

Man kann durch die andere Sprachgestaltung von Scala und dem Fokus auf funktionaler Programmierung wohl einiges geschickter und einfacher Formulieren, aber intern wirds dann doch auf Threads, ThreadPools, Futures und Callables/Runnables gemappt werden... :/
 
CapFuture schrieb:
Hmm... Ich wollte mich zwar seit längerem mit Scala beschäftigen, aber ein gedanke hat mich bis dato immer abgehalten: Scala kann nicht mehr können als Java, da es letztendlich nur Java ist.
Ja und nein ;)
Scala bildet genauso wie Java auf den Java-Bytecode ab. Jetzt frag mich aber nicht wie, aber Scala schafft es auf der Basis Features zu implementieren, die Java (noch) nicht kann. So gibt es Closures, es gibt ein deutlich besseres OOP-Modell, es gibt Traits, Tail-Recursion. Methodenüberladung usw.
Ich vermute dass der Scala-Compiler dies irgendwie geschickt in Java-Bytecode übersetzt, aber wie ist mir ein Rätsel.

CapFuture schrieb:
Ergo sind beide Sprachen gleich mächtig und sollte mit unterschieden im Overhead auch gleich schnell sein...
ja, sie sind ziemlich ähnlich ;)
Wobei eine neue Google-Studie Scala "bescheinigt" hat mehrfach langsamer als Java zu sein, interessanterweise spiegelt aber kein Benchmark des Language Benchmarks Game dies wieder, neija, schwer zu deuten.

CapFuture schrieb:
Man kann durch die andere Sprachgestaltung von Scala und dem Fokus auf funktionaler Programmierung wohl einiges geschickter und einfacher Formulieren, aber intern wirds dann doch auf Threads, ThreadPools, Futures und Callables/Runnables gemappt werden... :/
ja und nein. Es wird vieles auf Java-Strukturen gemappt werden, das stimmt, aber auch Dinge, die Java gar nicht kann oder dem Java-Modell deutlich überlegen sind.
Ich bin ehrlich, ich bin kein besonderer Freund von funktionaler Programmierung, manche Dinge kann man damit geschickt lösen, aber andere werden einfach unendlich kompliziert damit (Curying, partiell definierte Funktionen).
Aber eines liebe ich an Scala wirklich, das OOP-Modell ist einfach genial, es kann solch ein Unmengen an Boilerplate-Code vermieden werden und es ist eine ganze Ecke ausdrucksstärker als Java und einige "Eigenheiten" von Scala erlauben es richtig geniale Ideen zu nutzen, wenn man sich auf sie einlässt (Methoden wie Attribute nutzen).
 
CapFuture schrieb:
Hmm... Ich wollte mich zwar seit längerem mit Scala beschäftigen, aber ein gedanke hat mich bis dato immer abgehalten: Scala kann nicht mehr können als Java, da es letztendlich nur Java ist.


Das Argument relativiert sich aber heutzutage doch stark. VB.Net ist so gesehen auch nicht weniger mächtig als C#, trotzdem würden mich keine 10 Pferde dazu bringen, ab jetzt VB.Net zu nutzen. Es kommt ja auch noch auf andere Dinge an als die Mächtigkeit.
 
Zuletzt bearbeitet:
es lohnt sich auf jeden Fall die verschiedenen Programmier-Paradigmen zu verinnerlichen bzw. sich damit zu beschäftigen. Scala gehört wie Haskell, F#, OCaml ... zu den funktionalen Programmiersprachen. Dann gibt es noch die bekannte (allgegenwärtige) imperative Programmierung (Java, Basic, C..). Des Weiteren Logik-Programmierung (Prolog), Objektorientierte Programmierung. Die Liste ist natürlich nicht vollständig. Zu guter Letzt wird alles auf einen Prozessor imo einer Stack-Maschine ausgeführt, was das Argument mit der Mächtigkeit entwertet.

Imo ist eine funktionale Programmiersprache ein guter Anfang.
 
Zuletzt bearbeitet: (Korrektur Smalltalk->Prolog)
Sry fürs klugscheißen, aber Scala ist "objektfunktional".
es vereint das objektorienterte imperative Modell mit dem funktionalen Modell.
 
Scala kann nicht mehr können als Java, da es letztendlich nur Java ist.
Ergo sind beide Sprachen gleich mächtig und sollte mit unterschieden im Overhead auch gleich schnell sein...
Hierzu ist evtl. die theoretische Grundlage interessant:
http://de.wikipedia.org/wiki/Turing-Vollständigkeit
kurz Gesagt: Alle Programmiersprachen sind gleichmächtig und keine kann mehr als eine Touring-Maschine.

Auf "gleich schnell" zu schließen finde ich etwas übertrieben - und wie schon gesagt wurde. Es geht ja nicht um theoretisch maximal mögliche Geschwindigkeit sondern darum, wie schnell+einfach(=billig) sich multicore-skalierender Code schreiben lässt.
Hier scheint (ich habs nie benutzt..) Scala ja seine Stärke zu haben.
 
Zuletzt bearbeitet:
@kuddlmuddl: Wenn ich Turing-Mächtig gemeint hätte, hätte ich Turing-Mächtig geschrieben -.- Es geht um Sprachfeatures und wie mit ihnen etwas Ausdrücken kann um ein Ziel zu erreichen... Aber hinter Scala und Java hängt am Ende immernoch die gleiche JVM die einen Java Bytecode interpretiert... Man könnte sogar sagen, dass Scala nur ein Dialekt von Java ist...

D.h. am Ende kommts ehh wieder auf die selben Bytecode raus, aber wenn man sich mich Java-Threads und dem ganzen Nebenläufigenprogrammieren net auskennst, die vielen Sprachmittel nicht kennt, kann man schneller schlechteren Code schreiben als vielleicht in Scala, weil die Paradigmen besser auf sowas ausgerichtet sind...

Was man am Ende verwenden will, sollte jeder nach Kenntnissstand, Aufgabenzweck und Vorliebe entscheiden :)
 
CapFuture schrieb:
Aber hinter Scala und Java hängt am Ende immernoch die gleiche JVM die einen Java Bytecode interpretiert... Man könnte sogar sagen, dass Scala nur ein Dialekt von Java ist...
nach der Logik ist auch Java nur ein Dialekt von C, da beide im Endeffekt nur auf Assemblerebene abbilden.

CapFuture schrieb:
D.h. am Ende kommts ehh wieder auf die selben Bytecode raus, aber wenn man sich mich Java-Threads und dem ganzen Nebenläufigenprogrammieren net auskennst, die vielen Sprachmittel nicht kennt, kann man schneller schlechteren Code schreiben als vielleicht in Scala, weil die Paradigmen besser auf sowas ausgerichtet sind..
ich würde es ehrlich gesagt anders definieren: es ist unter Java schwerer korrekten Multi-Threaded Code zu produzieren, als unter Scala.
Wer mal "Java Concurrency in Practise" gelesen hat und die kapitel über das Java Memory Modell gelesen hat, weiß was ich meine. Zu gewährleisten, dass ein Thread nur gleichzeitig in einem Codeblock agiert ist leicht, die Visibility für alle Threads zu gewährleisten ist dagegen richtig einfach. Bisher funktionierte es bei den meisten (auch mir) aus reinem Zufall korrekt, weil die Caches geteilt werden, kommt man aber mal auf Rechner mit echten physischen CPUs bei denen die Wahrscheinlichkeit steigt, dass die gleichen Daten in 2 Caches stecken, dann treten Visibility-Fehler auf einmal sehr schnell auf.
 
Aye komm... Die sehn nur gleich aus, aber C und Java haben sonst nichts gemein... auf ASM Ebene wollen wir nicht gehen, also bitte... ;)

Und wie vermeidet Scala das? Cache-Alignment kannste unter so einer Hochsprache schlecht betreiben, oder?
 
CapFuture schrieb:
Und wie vermeidet Scala das? Cache-Alignment kannste unter so einer Hochsprache schlecht betreiben, oder?

Neija das wird eben durch das Actor-Framework garantiert. Dadurch dass du nicht mehr auf fremde Objekte zugreifst sondern nur jeder Aktor auf seinen eigenen Objekte, können die Cache-Fehler nicht auftreten. Das Actor-Framework kümemrt sich dann auch drum, dass der neue Thread die Daten sehen kann, sollte der Actor von 2 verschiedenen Threads hintereinander ausgeführt werden.
 
Zurück
Oben