Was ist Julia? Ein neuer Ansatz für numerisches Rechnen

Julia ist eine kostenlose Open-Source-Programmiersprache mit hohem Leistungsniveau und hoher Leistung für das numerische Rechnen. Es bietet den Entwicklungskomfort einer dynamischen Sprache mit der Leistung einer kompilierten statisch typisierten Sprache, teilweise dank eines auf LLVM basierenden JIT-Compilers, der nativen Maschinencode generiert, und teilweise dank eines Designs, das Typstabilität durch Spezialisierung über mehrere implementiert Versand, wodurch es einfach ist, zu effizientem Code zu kompilieren.

In dem Blog-Beitrag, in dem die erste Veröffentlichung von Julia im Jahr 2012 angekündigt wurde, gaben die Autoren der Sprache - Jeff Bezanson, Stefan Karpinski, Viral Shah und Alan Edelman - an, drei Jahre damit verbracht zu haben, Julia zu erschaffen, weil sie gierig waren . Sie hatten die Kompromisse zwischen Matlab, Lisp, Python, Ruby, Perl, Mathematica, R und C satt und wollten eine einzige Sprache, die sich gut für wissenschaftliches Rechnen, maschinelles Lernen, Data Mining und lineare Algebra im großen Maßstab eignet , paralleles Rechnen und verteiltes Rechnen.

Für wen ist Julia? Julia ist nicht nur für Forscher und Ingenieure attraktiv, sondern auch für Datenwissenschaftler sowie für Finanzanalysten und Quants.

Die Designer der Sprache und zwei weitere gründeten Julia Computing im Juli 2015, um „Produkte zu entwickeln, mit denen Julia einfach zu verwenden, einfach bereitzustellen und einfach zu skalieren ist“. Zum jetzigen Zeitpunkt beschäftigt das Unternehmen 28 Mitarbeiter und Kunden, die von nationalen Labors über Banken, Ökonomen bis hin zu autonomen Fahrzeugforschern reichen. Neben der Pflege der Julia Open Source-Repositories auf GitHub bietet Julia Computing kommerzielle Produkte an, darunter JuliaPro, das sowohl als kostenlose als auch als kostenpflichtige Version erhältlich ist.

Warum Julia?

Julia „möchte eine beispiellose Kombination aus Benutzerfreundlichkeit, Leistung und Effizienz in einer einzigen Sprache schaffen.“ Betrachten Sie zum Thema Effizienz die folgende Grafik:

Julia Computing

Julia Benchmarks

Was wir hier sehen, ist, dass Julia-Code für einige Arten von Operationen schneller als C und für andere nicht mehr als ein paar Mal langsamer als C sein kann. Vergleichen Sie das beispielsweise mit R, das bei einigen Operationen fast 1000-mal langsamer als C sein kann.

Beachten Sie, dass einer der langsamsten Tests für Julia die Fibonacci-Rekursion ist. Das liegt daran, dass Julia derzeit keine Optimierung der Schwanzrekursion bietet. Die Rekursion ist von Natur aus langsamer als die Schleife. Für echte Julia-Programme, die Sie in der Produktion ausführen möchten, möchten Sie die Schleifenform (Iterationsform) solcher Algorithmen implementieren.

Julia JIT Zusammenstellung

Der JIT-Compiler-Ansatz (Just-in-Time) ist im Gegensatz zu einem reinen Interpreter mit Kosten verbunden: Der Compiler muss den Quellcode analysieren und Maschinencode generieren, bevor Ihr Code ausgeführt werden kann. Dies kann eine spürbare Startzeit für Julia-Programme bedeuten, wenn jede Funktion und jedes Makro zum ersten Mal in einer Sitzung ausgeführt wird. Im folgenden Screenshot sehen wir also, dass beim zweiten Generieren einer Million zufälliger Gleitkommazahlen die benötigte Zeit um eine Größenordnung geringer ist als bei der ersten Ausführung. Sowohl das @timeMakro als auch die rand()Funktion mussten beim ersten Mal über den Code kompiliert werden, da die Julia-Bibliotheken in Julia geschrieben sind.

julia> @time rand (10 ^ 6);

  0,62081 Sekunden (14,44 k Zuweisungen: 8,415 MiB)

julia> @time rand (10 ^ 6);

  0,004881 Sekunden (7 Zuordnungen: 7,630 MiB)

Julia-Fans behaupten auf verschiedene Weise, dass Python, R oder sogar Matlab einfach zu bedienen sind. Diese Vergleiche sind genau zu prüfen, da die Julia-Sprache elegant, leistungsfähig und auf wissenschaftliches Rechnen ausgerichtet ist und die Bibliotheken eine breite Palette erweiterter Programmierfunktionen bieten.

Julia Beispiel

Betrachten Sie als kurzes Beispiel für die Julia-Sprache den folgenden Benchmark-Code für Mandelbrot-Sets:

Wie Sie sehen können, sind komplexe Zahlenarithmetik in die Sprache integriert, ebenso wie Makros für Tests und Timing. Wie Sie auch sehen können, fehlen in Julia die nachfolgenden Semikolons, die C-ähnliche Sprachen plagen, und die verschachtelten Klammern, die Lisp-ähnliche Sprachen plagen. Beachten Sie, dass dies mandelperf()in den Zeilen 61 und 62 zweimal aufgerufen wird. Der erste Aufruf testet das Ergebnis auf Richtigkeit und führt die JIT-Kompilierung durch. Der zweite Anruf erhält das Timing.

Julia Programmierung

Julia hat viele andere erwähnenswerte Eigenschaften. Zum einen sind benutzerdefinierte Typen so schnell und kompakt wie integrierte Typen. Tatsächlich können Sie abstrakte Typen deklarieren, die sich wie generische Typen verhalten, mit der Ausnahme, dass sie für die übergebenen Argumenttypen kompiliert werden.

Zum anderen bedeutet Julias integrierte Codevektorisierung, dass kein Programmierer Code für die Leistung vektorisieren muss. gewöhnlicher devektorisierter Code ist schnell. Der Compiler kann SIMD-Anweisungen und -Register nutzen, falls diese auf der zugrunde liegenden CPU vorhanden sind, und die Schleifen in einem sequentiellen Prozess abrollen, um sie so weit wie die Hardware zulässt zu vektorisieren. Sie können Schleifen mit der @simdAnmerkung als vektorisierbar markieren .

Julia Parallelität

Julia wurde auch für Parallelität und verteilte Berechnung entwickelt, wobei zwei Grundelemente verwendet wurden: Fernreferenzen und Fernaufrufe. Fernreferenzen gibt es in zwei Varianten:  Future und  RemoteChannel. A Futureist das Äquivalent eines JavaScript promise; a RemoteChannelist wiederbeschreibbar und kann für die Kommunikation zwischen Prozessen wie Unix pipeoder Go verwendet werden channel. Angenommen, Sie haben Julia mit mehreren Prozessen gestartet (z. B. julia -p 8für eine Acht-Kern-CPU wie einen Intel Core i7), können Sie @spawnoder remotecall()Funktionsaufrufe ausführen, um einen anderen Julia-Prozess asynchron auszuführen, und später fetch()den Futurezurückgegebenen, wenn Sie die synchronisieren und verwenden möchten Ergebnis.

Wenn Sie nicht auf mehreren Kernen ausgeführt werden müssen, können Sie leichtes „grünes“ Threading verwenden, das Task()in Julia als a und in einigen anderen Sprachen als coroutine bezeichnet wird. A Task()oder @taskarbeitet in Verbindung mit a Channel, der Einzelprozessversion von RemoteChannel.

Julia-Typ-System

Julia verfügt über ein unauffälliges und dennoch leistungsstarkes Typsystem, das standardmäßig dynamisch mit Laufzeittypinferenz ist, jedoch optionale Typanmerkungen zulässt. Dies ähnelt TypeScript. Zum Beispiel:

julia> (1 + 2) :: AbstractFloat

FEHLER: TypeError: typeassert: erwartet AbstractFloat, hat Int64

julia> (1 + 2) :: Int

3

Hier behaupten wir beim ersten Mal einen inkompatiblen Typ, der einen Fehler verursacht, und beim zweiten Mal einen kompatiblen Typ.

Julia Saiten

Julia bietet eine effiziente Unterstützung für Unicode-Zeichenfolgen und -Zeichen, die im UTF-8-Format gespeichert sind, sowie eine effiziente Unterstützung für ASCII-Zeichen, da in UTF-8 die Codepunkte unter 0x80 (128) in einem einzelnen Zeichen codiert sind. Andernfalls ist UTF-8 eine Codierung mit variabler Länge, sodass Sie nicht davon ausgehen können, dass die Länge einer Julia-Zeichenfolge dem letzten Zeichenindex entspricht.

Volle Unterstützung für UTF-8 bedeutet unter anderem, dass Sie Variablen einfach mit griechischen Buchstaben definieren können, wodurch der wissenschaftliche Julia-Code den Lehrbucherklärungen der Formeln sehr ähnlich sieht, z sin(2π). Es transcode()wird eine Funktion zum Konvertieren von UTF-8 in und von anderen Unicode-Codierungen bereitgestellt.

C- und Fortran-Funktionen

Julia kann C- und Fortran-Funktionen direkt aufrufen, ohne dass Wrapper oder spezielle APIs erforderlich sind. Sie müssen jedoch den vom Fortran-Compiler ausgegebenen „dekorierten“ Funktionsnamen kennen. Die externe C- oder Fortran-Funktion muss sich in einer gemeinsam genutzten Bibliothek befinden. Sie verwenden die Julia- ccall()Funktion für den eigentlichen Aufruf. Auf einem Unix-ähnlichen System können Sie diesen Julia-Code beispielsweise verwenden, um den Wert einer Umgebungsvariablen mithilfe der getenvFunktion in libc abzurufen:

Funktion getenv (var :: AbstractString)

     val = ccall ((: getenv, "libc"),

                 Cstring, (Cstring,), var)

     if val == C_NULL

         Fehler ("getenv: undefined variable:", var)

     Ende

     unsafe_string (val)

Ende

julia> getenv ("SHELL")

"/ bin / bash"

Julia-Makros

Julia hat Lisp-ähnliche Makros, die sich von den von C und C ++ verwendeten Makro-Präprozessoren unterscheiden. Julia verfügt auch über andere Metaprogrammierfunktionen wie Reflexion, Codegenerierung, Symbol- (z. B. :foo) und Ausdrucksobjekte (z. B. :(a+b*c+1)) eval()sowie generierte Funktionen. Julia-Makros werden zur Analysezeit ausgewertet.

Generierte Funktionen werden dagegen vor der Funktionskompilierung erweitert, wenn die Typen ihrer Parameter bekannt sind. Generierte Funktionen bieten die Flexibilität generischer Funktionen (wie in C ++ und Java implementiert) und die Effizienz stark typisierter Funktionen, da kein Laufzeitversand zur Unterstützung des parametrischen Polymorphismus erforderlich ist.

GPU-Unterstützung

Julia unterstützt die GPU unter anderem mit dem MXNet-Deep-Learning-Paket, der ArrayFire-GPU-Array-Bibliothek, den linearen Algebra- und tiefen neuronalen Netzwerkbibliotheken cuBLAS und cuDNN sowie dem CUDA-Framework für GPU-Computer für allgemeine Zwecke. Die Julia-Wrapper und ihre jeweiligen Bibliotheken sind in der folgenden Abbildung dargestellt.

Julia Computing

JuliaPro und Juno IDE

Sie können die kostenlose Open Source Julia-Befehlszeile für Windows, MacOS, generisches Linux oder generisches FreeBSD von der Julia-Sprachwebsite herunterladen. Sie können das Julia-Quellcode-Repository von GitHub klonen.

Alternativ können Sie JuliaPro von Julia Computing herunterladen. Zusätzlich zum Compiler bietet JuliaPro die atombasierte Juno-IDE (siehe unten) und mehr als 160 kuratierte Pakete, einschließlich Visualisierung und Plotten.

Über das kostenlose JuliaPro hinaus können Sie Abonnements für Unternehmensunterstützung, quantitative Finanzfunktionen, Datenbankunterstützung und Zeitreihenanalyse hinzufügen. JuliaRun ist ein skalierbarer Server für einen Cluster oder eine Cloud.

Jupyter-Notizbücher und IJulia

Zusätzlich zur Verwendung von Juno als Julia-IDE können Sie Visual Studio-Code mit der Julia-Erweiterung (direkt unten gezeigt) und Jupyter-Notebooks mit dem IJulia-Kernel (siehe zweiten und dritten Screenshots unten) verwenden. Möglicherweise müssen Sie Jupyter-Notebooks für Python 2 oder (vorzugsweise) Python 3 mit Anaconda oder pip installieren.

JuliaBox

Sie können Julia in Jupyter-Notizbüchern online mit JuliaBox (siehe unten), einem anderen Produkt von Julia Computing, ausführen, ohne eine Installation auf Ihrem lokalen Computer durchzuführen. JuliaBox enthält derzeit mehr als 300 Pakete, führt Julia 0.6.2 aus und enthält Dutzende von Tutorial-Jupyter-Notizbüchern. Die Liste der Tutorial-Ordner auf oberster Ebene wird unten angezeigt. Der kostenlose JuliaBox-Zugriff bietet Ihnen 90-minütige Sitzungen mit drei CPU-Kernen. Mit dem persönlichen Abonnement von 14 USD pro Monat erhalten Sie vierstündige Sitzungen mit fünf Kernen. Mit dem Pro-Abonnement für 70 US-Dollar pro Monat erhalten Sie achtstündige Sitzungen mit 32 Kernen. Der GPU-Zugang ist ab Juni 2018 noch nicht verfügbar.

Julia-Pakete

Julia "geht wie Python, läuft aber wie C." Wie mein Kollege Serdar Yegulalp im Dezember 2017 schrieb, beginnt Julia, Python für die datenwissenschaftliche Programmierung herauszufordern, und beide Sprachen haben Vorteile. Als Hinweis auf die schnell reifende Unterstützung für Data Science in Julia gibt es bereits zwei Bücher mit dem Titel Julia for Data Science , eines von Zacharias Voulgaris und das andere von Anshul Joshi, obwohl ich nicht über die Qualität von beiden sprechen kann einer.

Wenn Sie sich die unten am besten bewerteten Julia-Pakete von Julia Observer ansehen, sehen Sie einen Julia-Kernel für Jupyter-Notebooks, das Gadfly-Grafikpaket (ähnlich wie ggplot2in R), eine generische Plot-Oberfläche, mehrere Deep Learning- und Maschinenfunktionen Lernpakete, Differentialgleichungslöser, DataFrames, DSGE-Modelle (Dynamic Stochastic General Equilibrium) der New York Fed, eine Optimierungsmodellierungssprache und Schnittstellen zu Python und C ++. Wenn Sie diese allgemeine Liste etwas weiter unten durchgehen, finden Sie auch QuantEcon, PyPlot, ScikitLearn, ein Bioinformatik-Paket und eine Implementierung von Lazy-Listen für die funktionale Programmierung.

Wenn die Julia-Pakete für Ihre Anforderungen nicht ausreichen und die Python-Oberfläche Sie nicht dahin bringt, wo Sie hin möchten, können Sie auch ein Paket installieren, das Ihnen generische Schnittstellen zu R (RCall) und Matlab bietet.

Julia für Finanzanalysten und Quants

Quants und Finanzanalysten finden viele kostenlose Pakete, um ihre Arbeit zu beschleunigen, wie im folgenden Screenshot gezeigt. Darüber hinaus bietet Julia Computing die JuliaFin-Suite an, die aus Miletus (einem DSL für Finanzverträge),  JuliaDB (eine leistungsstarke In- Memory- und verteilte Datenbank),  JuliaInXL (Julia aus Excel- Tabellen aufrufen) und  Bloomberg- Konnektivität (Zugriff auf Real) besteht -Zeit und historische Marktdaten).