Der er umiddelbart klare forskelle mellem Go og Rust. Go har et stærkere fokus på at opbygge web-API’er og små tjenester, der kan skaleres i det uendelige, især med goroutines’ kraft. Sidstnævnte er også muligt med Rust, men tingene er meget sværere set ud fra en udvikleroplevelse.

Rust fungerer godt til behandling af store datamængder og andre CPU-intensive operationer, f.eks. udførelse af algoritmer. Dette er Rusts største fordel i forhold til Go. Projekter, der kræver høj ydeevne, er generelt bedre egnet til Rust.

I denne vejledning sammenligner og kontrasterer vi Go og Rust og evaluerer hvert programmeringssprog med hensyn til ydeevne, samtidighed, hukommelsesstyring og den overordnede udvikleroplevelse. Vi præsenterer også en oversigt over disse elementer for at hjælpe dig med at vælge det rigtige sprog til dit projekt på et øjeblik.

Hvis du lige er begyndt med Rust, kan det være en god idé at genopfriske denne begyndervejledning, før du læser videre.

Hvis du er helt opdateret, så lad os dykke ned i det!

Performance

Originalt designet af Googles ingeniører blev Go introduceret for offentligheden i 2009. Det blev skabt for at tilbyde et alternativ til C++, som var lettere at lære og kode, og som var optimeret til at køre på multicore-CPU’er.

Siden da har Go været fantastisk for udviklere, der ønsker at udnytte den samtidighed, sproget tilbyder. Sproget indeholder goroutiner, der gør det muligt at køre funktioner som underprocesser.

En stor fordel ved Go er, hvor nemt du kan bruge goroutiner. Du skal blot tilføje go-syntaksen til en funktion for at få den til at køre som en underproces. Go’s samtidighedsmodel giver dig mulighed for at distribuere arbejdsbelastninger på tværs af flere CPU-kerner, hvilket gør det til et meget effektivt sprog.

package mainimport ( "fmt" "time")func f(from string) { for i := 0; i < 3; i++ { fmt.Println(from, ":", i) }}func main() { f("direct") go f("goroutine") time.Sleep(time.Second) fmt.Println("done")}

Trods understøttelsen af multicore-CPU’er formår Rust stadig at overgå Go. Rust er mere effektiv i udførelsen af algoritmer og ressourceintensive operationer. Benchmarks Game sammenligner Rust og Go for forskellige algoritmer, f.eks. binære træer. For alle de testede algoritmer var Rust mindst 30 procent hurtigere; i forbindelse med beregninger af binære træer var det op til 1.000 procent. En undersøgelse fra Bitbucket viser lignende resultater, hvor Rust klarer sig på niveau med C++.

Rust Performance According to Bitbucket

Rust Performance According to Bitbucket

(Kilde: Benchmarks Game)

Concurrency

Som nævnt ovenfor understøtter Go concurrency. Lad os f.eks. sige, at du kører en webserver, der håndterer API-forespørgsler. Du kan bruge Go’s goroutiner til at køre hver anmodning som en underproces, hvilket maksimerer effektiviteten ved at aflaste opgaverne til alle tilgængelige CPU-kerner.

Goroutiner er en del af Go’s indbyggede funktioner, mens Rust kun har fået indbygget async/await-syntaks til at understøtte samtidighed. Som sådan går fordelen med hensyn til udvikleroplevelse til Go, når det gælder samtidighed. Rust er dog langt bedre til at garantere hukommelsessikkerhed.

Her er et eksempel på forenklede tråde til Rust:

use std::thread;use std::time::Duration;fn main() { // 1. create a new thread for i in 1..10 { thread::spawn(|| { println!("thread: number {}!", i); thread::sleep(Duration::from_millis(100)); }); } println!("hi from the main thread!");}

Samtidighed har altid været et ømtåleligt problem for udviklere. Det er ikke en let opgave at garantere hukommelsessikker samtidighed uden at gå på kompromis med udvikleroplevelsen. Dette ekstreme sikkerhedsfokus førte imidlertid til skabelsen af beviseligt korrekt samtidighed. Rust eksperimenterede med begrebet ejerskab for at forhindre uopfordret adgang til ressourcer for at forhindre fejl i hukommelsessikkerheden.

Rust tilbyder fire forskellige samtidighedsparadigmer for at hjælpe dig med at undgå almindelige faldgruber i forbindelse med hukommelsessikkerhed. Vi vil se nærmere på to almindelige paradigmer: kanal og lås.

Kanal

En kanal hjælper med at overføre en meddelelse fra en tråd til en anden. Mens dette koncept også findes i Go, giver Rust dig mulighed for at overføre en pointer fra en tråd til en anden for at undgå kapløbsbetingelser for ressourcer. Ved at overføre pointers kan Rust håndhæve trådisolation for kanaler. Igen viser Rust sin besættelse af hukommelsessikkerhed med hensyn til sin samtidighedsmodel.

Lock

Data er kun tilgængelige, når låsen er holdt. Rust er afhængig af princippet om at låse data i stedet for torsk, som ofte findes i programmeringssprog som Java.

For flere detaljer om ejerskabsbegrebet og alle samtidighedsparadigmer kan du læse “Fearless Concurrency with Rust.”

Hukommelsessikkerhed

Det tidligere koncept om ejerskab er et af Rusts vigtigste salgsargumenter. Rust tager type-sikkerhed, som også er vigtig for at muliggøre hukommelsessikker samtidighed, til det næste niveau.

Som det fremgår af Bitbucket-bloggen, “Rust’s very strict and pedantic compiler checks every variable you use and every memory address you reference. Den undgår mulige dataræsbetingelser og informerer dig om udefineret adfærd.”

Det betyder, at du ikke vil ende med et bufferoverløb eller en racebetingelse på grund af Rusts ekstreme besættelse af hukommelsessikkerhed. Dette har dog også sine ulemper. For eksempel skal du være hyperbevidst om principperne for hukommelsesallokering, mens du skriver kode. Det er ikke let altid at have hukommelsessikkerhedsvagten oppe.

Udviklererfaring

Først og fremmest skal vi se på den indlæringskurve, der er forbundet med hvert sprog. Go blev designet med enkelhed for øje. Udviklere omtaler det ofte som et “kedeligt” sprog, hvilket vil sige, at det begrænsede sæt af indbyggede funktioner gør Go let at tage til sig.

Dertil kommer, at Go tilbyder et lettere alternativ til C++, idet det skjuler aspekter som hukommelsessikkerhed og hukommelsesallokering. Rust anvender en anden tilgang og tvinger dig til at tænke over begreber som f.eks. hukommelsessikkerhed. Begrebet ejerskab og muligheden for at videregive pointers gør Rust til et mindre attraktivt alternativ at lære. Når du konstant tænker på hukommelsessikkerhed, er du mindre produktiv, og din kode vil nødvendigvis være mere kompleks.

Læringskurven for Rust er ret stejl sammenlignet med Go. Det er dog værd at nævne, at Go har en stejlere indlæringskurve end mere dynamiske sprog som Python og JavaScript.

Hvornår skal man bruge Go

Go fungerer godt til en lang række forskellige brugssituationer, hvilket gør det til et godt alternativ til Node.js til at skabe web-API’er. Som Loris Cro bemærkede: “Go’s samtidighedsmodel passer godt til server-side-programmer, der skal håndtere flere uafhængige anmodninger”. Det er netop derfor, at Go indeholder goroutiner.

Dertil kommer, at Go har indbygget understøttelse for HTTP-webprotokollen. Du kan hurtigt designe et lille API ved hjælp af den indbyggede HTTP-understøttelse og køre det som en mikroservice. Derfor passer Go godt til microservices-arkitekturen og opfylder API-udvikleres behov.

Kort sagt passer Go godt, hvis du lægger vægt på udviklingshastighed og foretrækker syntaksens enkelhed frem for ydeevne. Derudover giver Go bedre læsbarhed af koden, hvilket er et vigtigt kriterium for store udviklingsteams.

Vælg Go, når:

  • Du lægger vægt på enkelhed og læsbarhed
  • Du ønsker en nem syntaks til hurtigt at skrive kode
  • Du ønsker at bruge et mere fleksibelt sprog, der understøtter webudvikling

Når du skal bruge Rust

Rust er et godt valg, når ydelsen er vigtig, f.eks. når du skal behandle store datamængder. Desuden giver Rust dig finkornet kontrol over, hvordan tråde opfører sig, og hvordan ressourcer deles mellem tråde.

På den anden side kommer Rust med en stejl indlæringskurve og sænker udviklingshastigheden på grund af den ekstra kompleksitet i forbindelse med hukommelsessikkerhed. Dette er ikke nødvendigvis en ulempe; Rust garanterer også, at du ikke vil støde på fejl i forbindelse med hukommelsessikkerhed, da compileren kontrollerer hver eneste data pointer. I komplekse systemer kan denne garanti være praktisk.

Vælg Rust, når:

  • Du går op i ydeevne
  • Du ønsker finkornet kontrol over tråde
  • Du vægter hukommelsessikkerhed højere end enkelhed

Gå vs. Rust: Min ærlige holdning

Lad os starte med at fremhæve lighederne. Både Go og Rust er open source og designet til at understøtte mikrotjenestearkitekturen og parallelle datamiljøer. Begge optimerer udnyttelsen af de tilgængelige CPU-kerner gennem samtidighed.

Men i sidste ende, hvilket sprog er bedst?

Der er mange måder at gribe dette spørgsmål an på. Jeg vil anbefale, at du tænker over, hvilken type applikation du ønsker at bygge. Go tjener godt til at skabe webapplikationer og API’er, der udnytter dets indbyggede samtidighedsfunktioner og samtidig understøtter microservices-arkitekturen.

Du kan også bruge Rust til at udvikle en web-API, men det er ikke designet med dette anvendelsestilfælde i tankerne. Rusts fokus på hukommelsessikkerhed øger kompleksiteten og udviklingstiden, især for et ret simpelt web-API. Den større mængde kontrol, du har over din kode, giver dig dog mulighed for at skrive mere optimeret, hukommelseseffektiv og performant kode.

For at sige det så enkelt som muligt er debatten om Go versus Rust i virkeligheden et spørgsmål om enkelhed versus sikkerhed.

For flere perspektiver kan du læse “Choosing between Go and Rust.”

LogRocket: Fuld synlighed i produktions-Rust-apps

Det kan være svært at fejlfinde Rust-applikationer, især når brugerne oplever problemer, der er svære at reproducere. Hvis du er interesseret i at overvåge og spore ydeevnen for dine Rust-apps, automatisk at få fejl frem til overfladen og spore langsomme netværksanmodninger og indlæsningstid, så prøv LogRocket. LogRocket Dashboard Free Trial Banner

LogRocket er som en DVR til webapps, der optager bogstaveligt talt alt, hvad der sker på din Rust-app. I stedet for at gætte på, hvorfor problemer opstår, kan du samle og rapportere om, hvilken tilstand din applikation var i, da et problem opstod. LogRocket overvåger også din apps ydeevne og rapporterer målinger som klientens CPU-belastning, klientens hukommelsesforbrug og meget mere.

Moderniser den måde, du debugger dine Rust-apps på – begynd at overvåge gratis.

Articles

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.