Welche Programmiersprache sollte ich für sehr große Berechnungen nutzen (zb Eulersche Zahl)?
Hallo zusammen,
Ich arbeite und programmiere sehr gerne mit Java und das funktioniert auch immer gut. Gestern habe ich mich mit der Eulerschen Zahl e befasst und habe ein Javaprogramm geschrieben, um bis zu 200 tausend Nachkommastellen zu berechnen. Da stößt das Programm allerdings schon an ein paar Grenzen. Ich muss gestehen, dass das Programm nicht super effizient ist, aber trotzdem habe ich mich gefragt, ob Java überhaupt für so ein Problem geeignet ist.
Ich habe dann dasselbe Programm in Python geschrieben und festgestellt, dass schon bei 50 Tausend Nachkommastellen Pyhton dreimal so lange braucht wie Java, also kann ich das schonmal rausstreichen.
Jetzt gibt es aber ja noch einige weitere Programmiersprachen, ich hatte zum Beispiel an C++ gedacht. Ich habe nämlich herausgefunden, dass manche Leute mehrere Milliarden Nachkommastellen berechnet haben. Wie gesagt, mein Programm ist weit entfernt von effizient, aber ist Java dafür gemacht?
Welche Programmiersprache würdet ihr mir dafür empfehlen? Oder ist Java bereits die beste und ich sollte einfach den Algorithmus verbessern?
Danke an alle Antworten!
4 Antworten
sollte einfach den Algorithmus verbessern
Das hier. Bei derartig "rechenlastigen" Programmen ist die Performance von Java in der Gegend von C. Die Hotspot-VM kann teils besser optimieren als der statische Optimizer der besten C-Compiler. Schwieriger wird's nur bei GPU-Rechnerei, da muss man sowieso sowas wie (J)CUDA verwenden.
Wenn du aber ausführlich Gebrauch von bequemer Objektorientierung machst und massenweise Speicher anforderst, der den GC beschäftigt, wird der Vorteil wieder mehr als zunichtegemacht. Die allermeisten Performanceprobleme von Java löst der Garbage Collector aus - nicht weil er schlecht ist (Java hat einige der besten GC-Implementierungen überhaupt), sondern weil er Arbeit verursacht, die sonst nicht da wäre.
Wobei er sich natürlich nach Bibliotheken für Arbitrary Precision umsehen sollte, ggf. sogar mit BCD, wenns drauf ankommen sollte.
Die Mathematik wird gar nicht das Problem sein.
Übrigens gehe ich davon aus, dass du bei deiner Python-Implementierung nicht sowas wie Pandas verwendet hast. Die ganzen SciPy-Bibliotheken sind sauschnell (weil sie im Kern gar nicht in Python geschrieben sind).
Wobei man auch erstmal mit decimal rumspielen kann, wenns um 'größere' Zahlen geht.
Wenn dann wirklich ans numerisch eingemachte geht, sind SciPy oder vielleicht auch mpmath o.ä. eine Option.
Dann werde ich mir die Bibliotheken mal anschauen. Mit Mathematik war gemeint, dass ich mit sehr genauen Zahlen arbeite, was natürlich auch sehr an Rechenleistung zieht. Aber vielleicht können die Bibliotheken Abhilfe schaffen.
was natürlich auch sehr an Rechenleistung zieht
Natürlich, das soll es auch. Dein Programm soll die CPU genau damit beschäftigen, dann ist es (im Vergleich von Implementierungen desselben Algorithmus) effizient.
Egal welche Sprache Du verwendest, wirst Du Dich damit befassen müssen, was in der gegebenen Sprache schnell ist, und was nicht. Python und R sind für sich genommen beide sehr langsam, aber wenn man wissenschaftliche Bibliotheken verwendet, kann Python sehr viel schneller sein. Daher ist Python als BigData Analytics-Sprache durchaus beliebt.
C++ ist schnell, wenn es von Entwicklern genutzt wird, die wissen, was in C++ teuer ist. Ansonsten kann es bei praktisch gleichem Programm langsamer sein. Es gibt Sprachen die sind da "idiotensicherer".
Was meinst Du mit "ineffizient"?
Probiere mal
Python mit Scipy
OCaml
Julia
C++
Kann ich so alles unterschreiben! Habe zum Thema C++ in meiner Antwort auch noch einiges geschrieben, was deine Antwort ergänzt.
Das mit den Bibliotheken in Python habe ich auch schon gehört, dann ist es wohl etwas, womit ich mich mal befassen könnte. Mit ineffezient meine ich die Weise, wie das Programm die Stellen berechnet. Es werden immer in 100er Paketen Kommazahlen berechnet und dann zum Ergebnis addiert. Ich habe allerdings gelesen, dass das so mit die schlechteste (dafür einfachste) Methode ist und man viel effizienter rechnet, wenn man statt genauen Werten "Grenzwerte" berechnet, in denen sich die Nachkommastellen befinden müssen. Aber wenn du auch C++ empfehlst, werde ich es mir mal anschauen. Danke für die Antwort!
Die Wahl der Programmiersprache ist eher nebensächlich, weil sie in der Regel nur einen konstanten Faktor bei der Laufzeit ausmacht.
Wichtiger ist es, den Algorithmus zu beschleunigen — z.B. von 𝓞(n³) auf 𝓞(n²) — und aufzupassen, dass man das nicht durch eine ineffiziente Implementierung wieder kaputt macht. Dazu muss man aber die versteckten Laufzeit-Killer einer Sprache kennen.
Python ist prinzipiell langsamer als Java, aber ein Python-dict steckt eine Java-HashMap locker in die Tasche, und eine Python-Generatorfunktion schlägt jeden Java-Stream. Dadurch kann Python wesentlich schneller als Java werden.
In Deinem Algorithmus könnte das Erweitern des Ergebnisses in Python der Flaschenhals sein; mit einer Liste von Teilergebnissen und einem abschließenden join() bekommst Du das leicht in den Griff. Ein Profiler hilft Dir aber sicher mehr als solche Spekulationen.
Mein Tipp: Bleibe erst einmal bei Deiner Lieblingssprache und nutze einen Profiler, um alle vermeidbaren Zeitfresser zu lokalisieren und zu eliminieren. Danach kannst Du zumindest vorhersagen, wie lange das Programm für 200k Dezimalstellen brauchen würde.
Erst jetzt stellt sich die Frage, welche andere Programmiersprache das Ganze (um einen konstanten Faktor) beschleunigen könnte. Werden 99% der Laufzeit in map.get() verbraten, ist Python sicher eine gute Wahl. Ist es die Masse der numerischen Berechnungen, ist C vermutlich schneller, usw.
Kurz und knapp:
C++
Ist einfach eine sehr effiziente Sprache zum Rechnen
Du kannst auch Java mit JNI (JavaNativeInterface) nutzen
Damit lassen sich Methoden in z.B. C++ schreiben und dann in Java Aufrufen. Das ist aber nur schneller wenn diese Methode eher länger braucht. Ich nutze das z.B. Für Matrizen Berechnung
Ja, das habe ich mir schon gedacht. Leider kenne ich mich mit der Mathematik hinter dem Problem nicht gut genug aus, auch wenn ich mir etliche Dokumentationen dazu durchgelesen habe. Dann muss ich mich wohl erst einmal mehr mit der Effizienz befassen. Danke für die Antwort!