Gon ja Rustin välillä on selviä eroja. Go keskittyy vahvemmin web-rajapintojen ja pienten palveluiden rakentamiseen, jotka voivat skaalautua loputtomiin, erityisesti goroutiinien voimalla. Jälkimmäinen on mahdollista myös Rustilla, mutta asiat ovat paljon vaikeampia kehittäjäkokemuksen kannalta.
Rust toimii hyvin suurten datamäärien käsittelyyn ja muihin CPU-intensiivisiin operaatioihin, kuten algoritmien suorittamiseen. Tämä on Rustin suurin etu Go:hon verrattuna. Suurta suorituskykyä vaativat projektit sopivat yleensä paremmin Rustille.
Tässä opetusohjelmassa vertailemme Go:ta ja Rustia ja arvioimme kumpaakin ohjelmointikieltä suorituskyvyn, samanaikaisuuden, muistinhallinnan ja yleisen kehittäjäkokemuksen kannalta. Esitämme myös yleiskatsauksen näistä elementeistä, jotta voit valita projektisi kannalta oikean kielen yhdellä silmäyksellä.
Jos olet vasta aloittamassa Rustin käyttöä, voi olla hyvä idea tutustua tähän aloittelijan oppaaseen ennen kuin luet lisää.
Jos olet päässyt jyvälle, sukelletaan sisään!
Suorituskyky
Alun perin Googlen insinöörien suunnittelema Go esiteltiin yleisölle vuonna 2009. Se luotiin tarjoamaan C++:lle vaihtoehto, joka oli helpompi oppia ja koodata ja joka oli optimoitu toimimaan moniydinsuorittimilla.
Sen jälkeen Go on ollut loistava kehittäjille, jotka haluavat hyödyntää kielen tarjoamaa samanaikaisuutta. Kieli tarjoaa goroutiineja, joiden avulla voit ajaa funktioita aliprosesseina.
Gon suuri etu on se, miten helposti voit käyttää goroutiineja. Pelkkä go
-syntaksin lisääminen funktioon saa sen toimimaan aliprosessina. Gon samanaikaisuusmalli mahdollistaa työtehtävien jakamisen useammalle suorittimen ytimelle, mikä tekee siitä erittäin tehokkaan kielen.
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")}
Moniydinsuorittimien tuesta huolimatta Rust onnistuu silti päihittämään Gon. Rust on tehokkaampi algoritmien ja resurssi-intensiivisten operaatioiden suorittamisessa. Benchmarks-pelissä verrataan Rustia ja Go:ta eri algoritmeissa, kuten binääripuissa. Kaikissa testatuissa algoritmeissa Rust oli vähintään 30 prosenttia nopeampi; binääripuiden laskennassa jopa 1 000 prosenttia. Bitbucketin tutkimus osoittaa samankaltaisia tuloksia, joissa Rust suoriutuu C++:n kanssa samalla tasolla.
(Lähde: Benchmarks Game)
Rinnakkaisuus
Kuten edellä mainittiin, Go tukee rinnakkaisuutta. Sanotaan esimerkiksi, että käytät web-palvelinta, joka käsittelee API-pyyntöjä. Voit käyttää Go:n goroutiineja suorittaaksesi jokaisen pyynnön aliprosessina, jolloin maksimoit tehokkuuden kuormittamalla tehtäviä kaikille käytettävissä oleville suorittimen ytimille.
Goroutiinit ovat osa Go:n sisäänrakennettuja funktioita, kun taas Rust on saanut vain natiivin async/await-syntaksin tukemaan samanaikaisuutta. Näin ollen kehittäjäkokemuksen etulyöntiasema menee Go:lle, kun kyse on samanaikaisuudesta. Rust on kuitenkin paljon parempi muistiturvallisuuden takaamisessa.
Tässä on esimerkki yksinkertaistetuista säikeistä Rustille:
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!");}
Rinnakkaisuus on aina ollut hankala ongelma kehittäjille. Ei ole helppo tehtävä taata muistiturvallinen samanaikaisuus vaarantamatta kehittäjäkokemusta. Äärimmäinen turvallisuuspainotteisuus johti kuitenkin todistettavasti oikean samanaikaisuuden luomiseen. Rust kokeili omistajuuden käsitettä estääkseen resurssien ei-toivotun käytön muistiturvallisuusvirheiden ehkäisemiseksi.
Rust tarjoaa neljä erilaista samanaikaisuusparadigmaa, joiden avulla voit välttää yleiset muistiturvallisuuden sudenkuopat. Tarkastelemme lähemmin kahta yleistä paradigmaa: kanavaa ja lukitusta.
Kanava
Kanava auttaa siirtämään viestin säikeestä toiseen. Vaikka tämä käsite on olemassa myös Go:ssa, Rust mahdollistaa osoittimen siirtämisen säikeestä toiseen, jotta vältetään resurssien kilpaillut olosuhteet. Osoittimien siirtämisen avulla Rust voi pakottaa säikeiden eristämisen kanaville. Jälleen kerran Rust osoittaa pakkomielteensä muistiturvallisuuden suhteen sen samanaikaisuusmallin suhteen.
Lock
Tietoon pääsee käsiksi vain silloin, kun lukko on hallussa. Rust luottaa datan lukitsemisen periaatteeseen turskan sijasta, mikä on usein havaittavissa ohjelmointikielissä, kuten Javassa.
Lisätietoja omistajuuden käsitteestä ja kaikista samanaikaisuusparadigmoista löydät kirjasta ”Fearless Concurrency with Rust.”
Muistiturvallisuus
Aikaisemmin mainittu omistajuuden käsite on yksi Rustin tärkeimpiä myyntivaltteja. Rust vie tyyppiturvallisuuden, joka on tärkeää myös muistiturvallisen samanaikaisuuden mahdollistamiseksi, seuraavalle tasolle.
Bitbucket-blogin mukaan ”Rustin erittäin tiukka ja pedantti kääntäjä tarkistaa jokaisen käyttämäsi muuttujan ja jokaisen viittaamasi muistiosoitteen. Se välttää mahdolliset datan kilpajuoksutilanteet ja ilmoittaa sinulle määrittelemättömästä käyttäytymisestä.”
Tämä tarkoittaa, ettet päädy puskurin ylivuotoon tai kilpajuoksutilanteeseen Rustin äärimmäisen pakkomielteisen muistiturvallisuuden takia. Tällä on kuitenkin myös haittansa. Sinun on esimerkiksi oltava hypertietoinen muistinjakoperiaatteista koodia kirjoittaessasi. Ei ole helppoa pitää muistiturvallisuuden vartijaa aina ylhäällä.
Kehittäjän kokemus
Katsotaan ensin kuhunkin kieleen liittyvää oppimiskäyrää. Go on suunniteltu yksinkertaisuutta silmällä pitäen. Kehittäjät kutsuvat sitä usein ”tylsäksi” kieleksi, mikä tarkoittaa sitä, että sen rajallinen määrä sisäänrakennettuja ominaisuuksia tekee Go:sta helposti omaksuttavan.
Sen lisäksi Go tarjoaa helpomman vaihtoehdon C++:lle, sillä se kätkee sisäänsä esimerkiksi muistiturvallisuuden ja muistin allokaation kaltaisia seikkoja. Rust ottaa toisenlaisen lähestymistavan, pakottaen sinut ajattelemaan muistin turvallisuuden kaltaisia käsitteitä. Omistajuuden käsite ja mahdollisuus siirtää osoittimia tekevät Rustista vähemmän houkuttelevan vaihtoehdon oppia. Kun mietit jatkuvasti muistiturvallisuutta, olet vähemmän tuottava ja koodisi on väistämättä monimutkaisempaa.
Rustin oppimiskäyrä on melko jyrkkä verrattuna Go:hon. On kuitenkin syytä mainita, että Go:n oppimiskäyrä on jyrkempi kuin dynaamisempien kielten, kuten Pythonin ja JavaScriptin, oppimiskäyrä.
Milloin Go:ta kannattaa käyttää
Go toimii hyvin monenlaisissa käyttötapauksissa, mikä tekee siitä loistavan vaihtoehdon Node.js:lle web-rajapintojen luomiseen. Kuten Loris Cro toteaa, ”Gon samanaikaisuusmalli sopii hyvin palvelinpuolen sovelluksiin, joiden on käsiteltävä useita toisistaan riippumattomia pyyntöjä”. Juuri tästä syystä Go tarjoaa goroutiineja.
Lisäksi Go:ssa on sisäänrakennettu tuki HTTP-verkkoprotokollalle. Voit nopeasti suunnitella pienen API:n käyttämällä sisäänrakennettua HTTP-tukea ja ajaa sitä mikropalveluna. Siksi Go sopii hyvin mikropalveluarkkitehtuuriin ja palvelee API-kehittäjien tarpeita.
Lyhyesti sanottuna Go sopii hyvin, jos arvostat kehitysnopeutta ja pidät syntaksin yksinkertaisuutta suorituskyvyn sijaan. Tämän lisäksi Go tarjoaa parempaa koodin luettavuutta, mikä on tärkeä kriteeri suurille kehitystiimeille.
Valitse Go, kun:
- Huolesi on yksinkertaisuus ja luettavuus
- Haluat helpon syntaksin koodin nopeaan kirjoittamiseen
- Haluat käyttää joustavampaa kieltä, joka tukee web-kehitystä
Milloin kannattaa käyttää Rustia
Rust on loistava valinta silloin, kun suorituskyvyllä on väliä, esimerkiksi käsiteltäessäsi suuria tietomääriä. Lisäksi Rust antaa sinulle hienojakoisen hallinnan siitä, miten säikeet käyttäytyvät ja miten resursseja jaetaan säikeiden välillä.
Toisaalta Rustin mukana tulee jyrkkä oppimiskäyrä ja se hidastaa kehitysnopeutta muistiturvallisuuden ylimääräisen monimutkaisuuden vuoksi. Tämä ei välttämättä ole haitta; Rust myös takaa, että et törmää muistiturvallisuusvirheisiin, koska kääntäjä tarkistaa jokaisen datan osoittimen. Monimutkaisissa järjestelmissä tämä varmuus voi olla kätevä.
Valitse Rust, kun:
- huolehdit suorituskyvystä
- Haluat hienojakoista säikeiden hallintaa
- Arvostat muistiturvallisuutta yksinkertaisuuden edelle
Go vs. Rust: Rehellinen näkemykseni
Aloitetaan korostamalla yhtäläisyyksiä. Sekä Go että Rust ovat avoimen lähdekoodin ohjelmistoja, jotka on suunniteltu tukemaan mikropalveluarkkitehtuuria ja rinnakkaisia laskentaympäristöjä. Molemmat optimoivat käytettävissä olevien suorittimen ytimien käytön rinnakkaisuuden avulla.
Mutta loppujen lopuksi, mikä kieli on paras?
Tätä kysymystä voi lähestyä monella tavalla. Suosittelen miettimään, millaisen sovelluksen haluat rakentaa. Go palvelee hyvin web-sovellusten ja API:iden luomiseen, joissa hyödynnetään sen sisäänrakennettuja rinnakkaisuusominaisuuksia ja tuetaan samalla mikropalveluarkkitehtuuria.
Voit myös käyttää Rustia web-API:n kehittämiseen, mutta sitä ei ole suunniteltu tätä käyttötarkoitusta silmällä pitäen. Rustin keskittyminen muistiturvallisuuteen lisää monimutkaisuutta ja kehitysaikaa erityisesti melko yksinkertaisen web-rajapinnan osalta. Suurempi kontrollin määrä, joka sinulla on koodisi suhteen, mahdollistaa kuitenkin optimoidumman, muistitehokkaamman ja suorituskykyisemmän koodin kirjoittamisen.
Mahdollisimman yksinkertaisesti sanottuna Go vs. Rust-keskustelu on oikeastaan kysymys yksinkertaisuudesta vs. turvallisuudesta.
Lisänäkökulmia löydät artikkelista ”Go:n ja Rustin väliltä valitseminen.”
LogRocket: Täysi näkyvyys tuotannossa oleviin Rust-sovelluksiin
Rust-sovellusten virheenkorjaus voi olla hankalaa, varsinkin kun käyttäjät kokevat ongelmia, joita on vaikea jäljentää. Jos olet kiinnostunut tarkkailemaan ja seuraamaan Rust-sovellustesi suorituskykyä, tuomaan virheet automaattisesti esiin ja seuraamaan hitaita verkkopyyntöjä ja latausaikoja, kokeile LogRocketia.
LogRocket on kuin DVR verkkosovelluksille, joka tallentaa kirjaimellisesti kaiken, mitä Rust-sovelluksessasi tapahtuu. Sen sijaan, että arvailet, miksi ongelmia ilmenee, voit koota ja raportoida, missä tilassa sovelluksesi oli ongelman ilmetessä. LogRocket valvoo myös sovelluksesi suorituskykyä ja raportoi metriikoita, kuten asiakkaan suorittimen kuormitusta, asiakkaan muistin käyttöä ja paljon muuta.
Modernisoi Rust-sovellusten virheenkorjaustapasi – aloita seuranta ilmaiseksi.