Programmering

Hvad er Julia? En frisk tilgang til numerisk databehandling

Julia er et gratis open source, højt niveau, højtydende, dynamisk programmeringssprog til numerisk computing. Det har udviklingsbekvemmeligheden for et dynamisk sprog med ydeevnen for et kompileret statisk skrevet sprog, dels takket være en JIT-compiler baseret på LLVM, der genererer native maskinkode og dels til et design, der implementerer typestabilitet gennem specialisering via flere forsendelse, hvilket gør det let at kompilere til effektiv kode.

I blogindlægget, der annoncerede den første frigivelse af Julia i 2012, fortalte sprogets forfattere - Jeff Bezanson, Stefan Karpinski, Viral Shah og Alan Edelman - at de brugte tre år på at skabe Julia, fordi de var grådig. De var trætte af kompromiserne mellem Matlab, Lisp, Python, Ruby, Perl, Mathematica, R og C, og ville have et enkelt sprog, der ville være godt til videnskabelig computing, maskinindlæring, datamining, lineær algebra i stor skala , parallel computing og distribueret computing.

Hvem er Julia til? Ud over at være attraktiv for forskere og ingeniører er Julia også attraktiv for dataforskere og for finansanalytikere og -kvantiteter.

Sprogets designere og to andre grundlagde Julia Computing i juli 2015 for at "udvikle produkter, der gør Julia nemme at bruge, nemme at implementere og nemme at skalere." I skrivende stund har virksomheden 28 ansatte og kunder, der spænder fra nationale laboratorier til banker til økonomer til autonome køretøjsforskere. Ud over at vedligeholde Julia open source-arkiver på GitHub tilbyder Julia Computing kommercielle produkter, herunder JuliaPro, der kommer i både gratis og betalte versioner.

Hvorfor Julia?

Julia "sigter mod at skabe en hidtil uset kombination af brugervenlighed, magt og effektivitet på et enkelt sprog." For spørgsmålet om effektivitet skal du overveje nedenstående graf:

Julia Computing

Julia-benchmarks

Hvad vi ser her er, at Julia-koden kan være hurtigere end C for et par slags operationer og ikke mere end et par gange langsommere end C for andre. Sammenlign det med for eksempel R, som kan være næsten 1.000 gange langsommere end C for nogle operationer.

Bemærk, at en af ​​de langsomste tests for Julia er Fibonacci-rekursion; det er fordi Julia i øjeblikket mangler optimering af halen rekursion. Rekursion er i sagens natur langsommere end looping. For ægte Julia-programmer, som du vil køre i produktion, vil du gerne implementere loop (iteration) form af sådanne algoritmer.

Julia JIT kompilering

Der er en pris for JIT (just-in-time) compiler tilgang i modsætning til en ren tolk: Compileren skal analysere kildekoden og generere maskinkode, før din kode kan køre. Det kan betyde en mærkbar opstartstid for Julia-programmer første gang hver funktion og makro kører i en session. Så i skærmbilledet nedenfor ser vi, at anden gang vi genererer en million tilfældige flydende numre, er tiden taget en størrelsesorden mindre end ved den første udførelse. Både @tid makro og rand () funktion skulle kompileres første gang gennem koden, fordi Julia-bibliotekerne er skrevet i Julia.

julia> @time rand (10 ^ 6);

0,62081 sekunder (14,44 k allokeringer: 8,415 MiB)

julia> @time rand (10 ^ 6);

0.004881 sekunder (7 tildelinger: 7.630 MiB)

Julia-fans hævder forskelligt, at det er let at bruge Python, R eller endda Matlab. Disse sammenligninger undersøger, da Julia-sproget er elegant, kraftfuldt og orienteret mod videnskabelig databehandling, og bibliotekerne leverer en bred vifte af avanceret programmeringsfunktionalitet.

Julia eksempel

Som et hurtigt eksempel på Julia-sprog, overvej følgende Mandelbrot-sæt benchmark-kode:

Som du kan se, er kompleks aritmetik indbygget i sproget, ligesom makroer til test og timing. Som du også kan se, er de efterfølgende semikoloner, der plager C-lignende sprog, og de indlejrede parenteser, der plager Lisp-lignende sprog, fraværende fra Julia. Noter det mandelperf () kaldes to gange, i linje 61 og 62. Det første opkald tester resultatet for korrekthed og udfører JIT-kompilering; det andet opkald får timingen.

Julia programmering

Julia har mange andre funktioner, der er værd at nævne. For det første er brugerdefinerede typer lige så hurtige og kompakte som indbyggede. Faktisk kan du erklære abstrakte typer, der opfører sig som generiske typer, bortset fra at de er kompileret for de argumenttyper, som de sendes.

For en anden betyder Julias indbyggede kodevektorisering, at der ikke er behov for en programmør til at vektorisere kode til ydeevne; almindelig afviklet kode er hurtig. Compileren kan drage fordel af SIMD-instruktioner og registre, hvis de findes på den underliggende CPU, og rulle løkkerne ud i en sekventiel proces for at vektorisere dem så meget, som hardware tillader. Du kan markere sløjfer som vektoriserbare med @simd kommentar.

Julia parallelitet

Julia blev også designet til parallelisme og distribueret beregning ved hjælp af to primitiver: fjernreferencer og fjernopkald. Fjernreferencer findes i to varianter:Fremtid ogRemoteChannel. EN Fremtid svarer til et JavaScript løfte; -en RemoteChannel kan omskrives og kan bruges til inter-proces kommunikation, som en Unix rør eller en Go kanal. Forudsat at du har startet Julia med flere processer (f.eks. julia -p 8 til en otte-core CPU, såsom en Intel Core i7), kan du @spawn eller fjernopkald () funktionskald til at udføre en anden Julia-proces asynkront og senere hente () det Fremtid returneres, når du vil synkronisere og bruge resultatet.

Hvis du ikke har brug for at køre på flere kerner, kan du bruge letvægts "grøn" trådning, kaldet a Opgave() i Julia og en coroutine på nogle andre sprog. EN Opgave() eller @opgave fungerer sammen med en Kanal, som er single-process version af RemoteChannel.

Julia-system

Julia har et diskret, men alligevel kraftfuldt typesystem, der som standard er dynamisk med kørselstypetype, men som muliggør valgfri typebemærkninger. Dette svarer til TypeScript. For eksempel:

julia> (1 + 2) :: AbstractFloat

FEJL: TypeFejl: typeassert: forventet AbstractFloat, fik Int64

julia> (1 + 2) :: Int

3

Her hævder vi en inkompatibel type første gang, der forårsager en fejl, og en kompatibel type anden gang.

Julia strenger

Julia har effektiv understøttelse af Unicode-strenge og tegn, der er gemt i UTF-8-format, samt effektiv support til ASCII-tegn, da kodepunkter i UTF-8 mindre end 0x80 (128) er kodet i et enkelt tegn. Ellers er UTF-8 en kodning med variabel længde, så du kan ikke antage, at længden af ​​en Julia-streng er lig med det sidste tegnindeks.

Fuld understøttelse af UTF-8 betyder blandt andet, at du let kan definere variabler ved hjælp af græske bogstaver, hvilket kan få videnskabelig Julia-kode til at ligne meget på lærebogens forklaringer på formlerne, f.eks. synd (2π). EN transkode () funktion til rådighed til at konvertere UTF-8 til og fra andre Unicode-kodninger.

C og Fortran funktioner

Julia kan ringe direkte til C- og Fortran-funktionerne uden indpakning eller specielle API'er, selvom du har brug for at kende det "dekorerede" funktionsnavn, der udsendes af Fortran-kompilatoren. Den eksterne C- eller Fortran-funktion skal være i et delt bibliotek; du bruger Julia ccall () funktion til det faktiske opkald. For eksempel kan du på et Unix-lignende system bruge denne Julia-kode til at få en miljøvariabels værdi ved hjælp af getenv funktion i libc:

funktion getenv (var :: AbstractString)

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

Cstring, (Cstring,), var)

hvis val == C_NULL

fejl ("getenv: udefineret variabel:", var)

ende

usikker_streng (val)

ende

julia> getenv ("SHELL")

"/ bin / bash"

Julia makroer

Julia har Lisp-lignende makroer, som adskiller sig fra de makroforprocessorer, der bruges af C og C ++. Julia har også andre metaprogrammeringsfaciliteter, såsom refleksion, kodegenerering, symbol (f.eks. : foo) og ekspression (f.eks. : (a + b * c + 1) ) genstande, eval ()og genererede funktioner. Julia-makroer evalueres ved parsetid.

Genererede funktioner udvides på den anden side, når typerne af deres parametre er kendt, inden funktions kompilering. Genererede funktioner har fleksibiliteten i generiske funktioner (som implementeret i C ++ og Java) og effektiviteten af ​​stærkt typede funktioner ved at eliminere behovet for kørselsforsendelse for at understøtte parametrisk polymorfisme.

GPU-understøttelse

Julia har GPU-understøttelse ved hjælp af blandt andet MXNet deep learning-pakken, ArrayFire GPU-arraybiblioteket, cuBLAS og cuDNN lineær algebra og dybe neurale netværksbiblioteker og CUDA-rammen til GPU-beregning til generelle formål. Julia-indpakningerne og deres respektive biblioteker er vist i nedenstående diagram.

Julia Computing

JuliaPro og Juno IDE

Du kan downloade den gratis open source Julia-kommandolinje til Windows, MacOS, generisk Linux eller generisk FreeBSD fra webstedet Julia-sprog. Du kan klone Julia-kildekoden fra GitHub.

Alternativt kan du downloade JuliaPro fra Julia Computing. Ud over compileren giver JuliaPro dig den Atom-baserede Juno IDE (vist nedenfor) og mere end 160 kuraterede pakker inklusive visualisering og plotting.

Ud over hvad der findes i den gratis JuliaPro, kan du tilføje abonnementer til virksomhedsstøtte, kvantitativ økonomifunktionalitet, databasesupport og tidsserie-analyse. JuliaRun er en skalerbar server til en klynge eller sky.

Jupyter notesbøger og IJulia

Ud over at bruge Juno som din Julia IDE, kan du bruge Visual Studio Code med Julia-udvidelsen (vist direkte nedenfor) og Jupyter-notesbøger med IJulia-kernen (vist i det andet og tredje skærmbillede nedenfor). Du skal muligvis installere Jupyter-notesbøger til Python 2 eller (helst) Python 3 med Anaconda eller pip.

JuliaBox

Du kan køre Julia i Jupyter-notesbøger online ved hjælp af JuliaBox (vist nedenfor), et andet produkt fra Julia Computing uden at foretage nogen installation på din lokale maskine. JuliaBox inkluderer i øjeblikket mere end 300 pakker, kører Julia 0.6.2 og indeholder snesevis af Jupyter-notesbøger til tutorial. Den øverste liste over tutorial-mapper vises nedenfor. Det gratis niveau af JuliaBox-adgang giver dig 90-minutters sessioner med tre CPU-kerner; det personlige abonnement på $ 14 pr. måned giver dig fire timers sessioner med fem kerner; og $ 70 pr. måned pro-abonnement giver dig otte timers sessioner med 32 kerner. GPU-adgang er endnu ikke tilgængelig fra juni 2018.

Julia-pakker

Julia "går som Python, men løber som C." Som min kollega Serdar Yegulalp skrev i december 2017, begynder Julia at udfordre Python til datavidenskabsprogrammering, og begge sprog har fordele. Som en indikation af den hurtigt modne støtte til datavidenskab i Julia, skal du overveje, at der allerede er to bøger med titlen Julia for datalogi, den ene af Zacharias Voulgaris, og den anden af ​​Anshul Joshi, selvom jeg ikke kan tale om kvaliteten af ​​nogen af ​​dem.

Hvis du ser på de overordnede højest vurderede Julia-pakker fra Julia Observer, vist nedenfor, vil du se en Julia-kerne til Jupyter-notesbøger, Gadfly-grafikpakken (ligner ggplot2 i R), en generisk plotningsgrænseflade, flere dyb lærings- og maskinindlæringspakker, differentialligningsopløsere, DataFrames, New York Fed dynamiske stokastiske generelle ligevægtsmodeller (DSGE) modeller, et optimeringsmodelleringssprog og grænseflader til Python og C ++. Hvis du går lidt længere ned på denne generelle liste, finder du også QuantEcon, PyPlot, ScikitLearn, en bioinformatikpakke og en implementering af dovne lister til funktionel programmering.

Hvis Julia-pakkerne ikke er tilstrækkelige til dine behov, og Python-grænsefladen ikke får dig, hvor du vil hen, kan du også installere en pakke, der giver dig generiske grænseflader til R (RCall) og Matlab.

Julia til finansanalytikere og kvantiteter

Quants og finansanalytikere finder mange gratis pakker til at fremskynde deres arbejde, som vist i skærmbilledet nedenfor. Derudover tilbyder Julia Computing JuliaFin-pakken, der består af Miletus (en DSL for finansielle kontrakter),JuliaDB (en højtydende in-memory og distribueret database),JuliaInXL (ring til Julia fra Excel-ark), ogBloomberg tilslutningsmuligheder (adgang til realtids- og historiske markedsdata).