本文翻譯自喬納森·特納(Jonathan Turner)和史蒂夫·弗朗西亞(Steve Francia)的文章《Rust vs. Go: Why They’re Better Together》
史蒂夫·弗朗西亞(Steve Francia)在過去的25年里建立了一些最具創(chuàng)新性和成功的技術(shù)和公司,這些技術(shù)和公司已經(jīng)成為云計(jì)算的基礎(chǔ),,被全世界的企業(yè)和開發(fā)者所接受,。他目前是谷歌Go編程語言的產(chǎn)品和戰(zhàn)略負(fù)責(zé)人。他是Hugo,、Cobra,、Viper、spf13-vim和許多其他開源項(xiàng)目的創(chuàng)建者,,擁有領(lǐng)導(dǎo)世界上最大的五個(gè)開源項(xiàng)目的獨(dú)特榮譽(yù),。 喬納森·特納(Jonathan Turner)在開源領(lǐng)域工作了20多年,從小型項(xiàng)目到大型項(xiàng)目,,包括幫助微軟向開源轉(zhuǎn)型,。他是創(chuàng)建TypeScript團(tuán)隊(duì)的一員,并作為項(xiàng)目經(jīng)理和設(shè)計(jì)團(tuán)隊(duì)的負(fù)責(zé)人幫助其成長,。他還作為Rust社區(qū)成員和Mozilla Rust團(tuán)隊(duì)的一員參與Rust的工作,包括共同設(shè)計(jì)Rust的錯(cuò)誤信息和IDE支持,。 雖然其他人可能認(rèn)為Rust和Go是競爭性的編程語言,,但Rust和Go團(tuán)隊(duì)卻都不這么認(rèn)為。恰恰相反,,我們的團(tuán)隊(duì)非常尊重其他團(tuán)隊(duì)正在做的事情,,并認(rèn)為這兩種編程語言是相輔相成的,有著共同的愿景,,即在整個(gè)行業(yè)內(nèi)實(shí)現(xiàn)軟件開發(fā)狀態(tài)的現(xiàn)代化,。在本文中,我們將討論Rust和Go的優(yōu)缺點(diǎn),、它們?nèi)绾蜗嗷パa(bǔ)充和支持以及我們對(duì)每種語言的最佳使用時(shí)機(jī)的建議,。一些公司正在發(fā)掘采用這兩種語言的價(jià)值以及它們的互補(bǔ)價(jià)值。為了從我們的觀點(diǎn)轉(zhuǎn)向用戶的實(shí)際體驗(yàn),,我們采訪了三家這樣的公司,,Dropbox 、Fastly和Cloudflare,,講述了他們共同使用Go和Rust的經(jīng)驗(yàn),。他們的經(jīng)驗(yàn)之談將被引用并貫穿本文,,為大家提供更進(jìn)一步的觀點(diǎn)。編程語言 | Go | Rust |
---|
創(chuàng)建時(shí)間 | 2009 | 2010 | 創(chuàng)建于 | 谷歌 | Mozilla | 知名項(xiàng)目 | Kubernetes,,Docker,,Github CLI,Hugo,,Caddy,,Drone,Ethereum,,Syncthing,,Terraform | Firefox,ripgrep,,alacritty, deno,,Habitat | 典型用途 | APIs,Web Apps,,CLI Apps,,DevOps,Networking,,Data Processing,,cloud apps | IoT,processing engines,,security-sensitive apps,,system components,cloud apps | 開發(fā)者采用 | 8.8%(第12名) | 5.1%(第19名) | 開發(fā)者最愛 | 62.3%(第5名) | 86.1%(第1名) | 開發(fā)最想要 | 17.9%(第3名) | 14.6%(第5名) | Go和Rust有很多共同點(diǎn),。兩者都是現(xiàn)代軟件語言,,都是出于為影響軟件開發(fā)的問題提供一個(gè)安全和可擴(kuò)展的解決方案的需要而誕生的。兩者都是為了應(yīng)對(duì)創(chuàng)建者在行業(yè)內(nèi)現(xiàn)有語言中遇到的缺點(diǎn)而創(chuàng)建的,,尤其是開發(fā)者生產(chǎn)力,、可擴(kuò)展性、安全性和并發(fā)性方面的缺點(diǎn),。當(dāng)今流行的大多數(shù)語言都是30多年前設(shè)計(jì)的,。當(dāng)這些語言被設(shè)計(jì)出來的時(shí)候,與今天有五個(gè)關(guān)鍵的區(qū)別:摩爾定律被認(rèn)為是永恒不變的,。 大多數(shù)軟件項(xiàng)目都是由小團(tuán)隊(duì)編寫的,,并且經(jīng)常一個(gè)人單干。 大多數(shù)軟件有相對(duì)較少的依賴性,,大多數(shù)是專有的,。 安全性是次要的考慮因素......或者根本不是考慮因素。 軟件通常是為單一平臺(tái)編寫的。 相比之下,,Rust和Go都是為今天的世界而寫的,,并都采取了相似的方法來設(shè)計(jì)一種適合今天開發(fā)需求的語言。Go和Rust都是專注于生產(chǎn)高效代碼的編譯語言,。它們還可以方便地使用當(dāng)今機(jī)器的多個(gè)處理器,,使它們成為編寫高效并行代碼的理想語言。“使用Go使得MercadoLibre公司將他們用于這項(xiàng)服務(wù)的服務(wù)器數(shù)量減少到原來的八分之一(從32臺(tái)服務(wù)器減少到4臺(tái)),,另外,,每臺(tái)服務(wù)器可以用更少的功率運(yùn)行(原來是4個(gè)CPU核,現(xiàn)在減少到2個(gè)CPU核),。有了Go,,該公司省去了88%的服務(wù)器,并將剩余服務(wù)器上的CPU削減了一半——產(chǎn)生了巨大的成本節(jié)約,?!薄禡ercadoLibre與Go一起成長》“在我們嚴(yán)格管理的環(huán)境中,在我們運(yùn)行Go代碼的環(huán)境中,,我們看到CPU減少了大約百分之十(與C++相比),,代碼更干凈,更可維護(hù),?!薄禕ala Natarajan,Paypal》“在AWS,,我們也很喜歡Rust,,因?yàn)樗軒椭鶤WS編寫高性能、安全的基礎(chǔ)設(shè)施級(jí)網(wǎng)絡(luò)和其他系統(tǒng)軟件,。亞馬遜第一個(gè)用Rust構(gòu)建的重要產(chǎn)品Firecracker于2018年公開發(fā)布,,它提供了開源虛擬化技術(shù),為AWS Lambda和其他無服務(wù)器產(chǎn)品提供動(dòng)力,。但我們也使用Rust來提供亞馬遜簡單存儲(chǔ)服務(wù)(Amazon S3),、亞馬遜彈性計(jì)算云(Amazon EC2),、Amazon CloudFront,、Amazon Route 53等服務(wù)。最近,,我們推出了基于Linux的容器操作系統(tǒng)Bottlerocket,,它是用Rust編寫的?!薄禡att Asay,,亞馬遜網(wǎng)絡(luò)服務(wù)》我們“看到我們速度非凡地提高了1200-1500%!我們從實(shí)現(xiàn)了較少解析規(guī)則的Scala的模式下的300-450ms,到實(shí)現(xiàn)了更多解析模式的Rust模式下的25-30ms,!”——Josh Hannaford,,IBM團(tuán)隊(duì)可擴(kuò)展——可審查今天的軟件開發(fā)是由團(tuán)隊(duì)建立的,這些團(tuán)隊(duì)不斷成長和擴(kuò)大,,經(jīng)常使用源碼控制以分布式的方式進(jìn)行協(xié)作,。Go和Rust都是針對(duì)團(tuán)隊(duì)的工作方式而設(shè)計(jì)的,通過消除不必要的擔(dān)憂,,如格式(比如go的gofmt),、安全和復(fù)雜的組織,來改善代碼審查,。這兩種語言都需要相對(duì)較少的上下文來理解代碼的工作,,使審查人員能夠更快速地使用其他人編寫的代碼,并審查團(tuán)隊(duì)成員的代碼和你團(tuán)隊(duì)以外的開源開發(fā)人員貢獻(xiàn)的代碼,。“我早期的職業(yè)生涯有Java和Ruby的背景,,構(gòu)建Go和Rust代碼對(duì)我來說就像卸下了無法承受的重?fù)?dān)。當(dāng)我在Google時(shí),,遇到用Go編寫的服務(wù)讓我很欣慰,,因?yàn)槲抑浪子跇?gòu)建和運(yùn)行。Rust的情況也是如此,,盡管我只是在更小的工作范圍內(nèi)使用了它,。我希望無限可配置的構(gòu)建系統(tǒng)的日子已經(jīng)過去了,而語言都有自己的專用構(gòu)建工具,,開箱即用,。”——Sam Rose,,CV合伙人“用Go寫服務(wù)的時(shí)候,,我往往會(huì)松一口氣,因?yàn)榕c動(dòng)態(tài)語言相比,,Go的靜態(tài)類型系統(tǒng)非常簡單,,易于推理,并發(fā)性是一等公民,,Go的標(biāo)準(zhǔn)庫既無比精致強(qiáng)大,,又切中要害。安裝一個(gè)標(biāo)準(zhǔn)的Go,,再使用一個(gè)gRPC庫和一個(gè)數(shù)據(jù)庫連接器,,你在服務(wù)器端幾乎不需要其他的東西,每個(gè)工程師都能看懂代碼,,看懂庫,。在用Rust編寫模塊時(shí),,Dropbox工程師在2019年Async-await穩(wěn)定下來之前,感受到了Rust在服務(wù)器端的成長之痛,,但從那時(shí)起,,crate(譯注:Rust中的概念)正在趨向于使用它,我們得到了Async模式并從并發(fā)中受益,?!薄狣aniel Reiter Horn,Dropbox今天一般軟件項(xiàng)目所使用的依賴關(guān)系數(shù)量是驚人的,。長達(dá)幾十年的軟件重用目標(biāo)在現(xiàn)代開發(fā)中已經(jīng)實(shí)現(xiàn),,今天的軟件可能是復(fù)用了100多個(gè)項(xiàng)目而構(gòu)建的。為此,,開發(fā)人員使用軟件倉庫,,這越來越成為軟件開發(fā)的主旋律,并在越來越廣泛的領(lǐng)域應(yīng)用,。開發(fā)者所包含的每一個(gè)軟件包,,又有自己的依賴關(guān)系。為今天的編程環(huán)境而設(shè)計(jì)出的編程語言需要毫不費(fèi)力地處理這種復(fù)雜性,。Go和Rust都有包管理系統(tǒng),,允許開發(fā)人員列出一個(gè)簡單的清單,列出他們想要構(gòu)建的包,,語言工具就會(huì)自動(dòng)為他們獲取和維護(hù)這些包,,這樣開發(fā)人員就可以把更多的精力放在自己的代碼上,而不是放在對(duì)其他包的管理上,。Go和Rust都很好地解決了當(dāng)今應(yīng)用的安全問題,,保證了用這些語言構(gòu)建的代碼在運(yùn)行時(shí)不會(huì)讓用戶暴露在各種經(jīng)典的安全漏洞中,比如緩沖區(qū)溢出,、use-after-free(內(nèi)存釋放后還使用)等,。通過消除這些顧慮,開發(fā)者可以專注于手頭的問題,,并在默認(rèn)情況下構(gòu)建更安全的應(yīng)用程序,。“Rust編譯器在解決您遇到的錯(cuò)誤時(shí)確實(shí)能助您一臂之力。這樣一來,,您就可以專注于自己的業(yè)務(wù)目標(biāo),,而不必尋找錯(cuò)誤或解密隱秘消息?!薄狫osh Hannaford,,IBM“簡而言之,,Rust的靈活性,,安全性和安全性帶給我們的益處超過了必須遵循嚴(yán)格的lifetime,,borrow(Rust中的概念)和其他編譯器規(guī)則甚至缺乏垃圾收集器所帶來的任何不便。這些功能是云軟件項(xiàng)目中非常需要的功能,,將有助于避免其中常見的許多錯(cuò)誤,。”——泰勒·托馬斯(Taylor Thomas),,微軟,。“Go是強(qiáng)靜態(tài)類型化的,沒有隱式轉(zhuǎn)換,,但語法開銷還是小得驚人,。這是通過賦值中簡單的類型推理與非類型化的數(shù)值常量一起實(shí)現(xiàn)的。這使得Go比Java(有隱式轉(zhuǎn)換)具有更強(qiáng)的類型安全性,,但代碼讀起來更像Python(有非類型變量),。”——Stefan Nilsson,,計(jì)算機(jī)科學(xué)教授,。“當(dāng)我們?cè)贒ropbox構(gòu)建用于存儲(chǔ)塊數(shù)據(jù)的Brotli壓縮庫時(shí),我們將自己限制在Rust的安全子集上,,而且,,也限制在核心庫(no-stdlib)上,分配器指定為通用,。這樣使用Rust的子集,,使得在客戶端從Rust調(diào)用Rust-Brotli庫,以及在服務(wù)器上使用Python和Go的C FFI變得非常容易,。這種編譯模式也提供了大量的安全保障,。經(jīng)過一些調(diào)整,Rust Brotli的實(shí)現(xiàn)盡管是100%安全的,、經(jīng)過數(shù)組邊界檢查的代碼,,但仍然比C語言中相應(yīng)的原生Brotli代碼快?!薄狣aniel Reiter Horn,,Dropbox在Go和Rust中,寫一個(gè)軟件,,在許多不同的操作系統(tǒng)和架構(gòu)上運(yùn)行是很容易的,。“一次編寫,,隨處編譯” ,。此外,Go和Rust都原生支持交叉編譯,,消除了舊編譯語言常見的“build farm”的需要,。“Go在生產(chǎn)優(yōu)化方面擁有很好的特質(zhì),,比如擁有較小的內(nèi)存占用,這支持其在大型項(xiàng)目中被用于構(gòu)建模塊,,以及開箱即用,,易于交叉編譯到其他架構(gòu)。由于Go代碼被編譯成單一的靜態(tài)二進(jìn)制,,我們可以輕松將其容器化,,并且通過擴(kuò)展,我們可以很輕松地將Go部署到任何高可用環(huán)境(如Kubernetes)中,?!薄狣ewet Diener,Curve,。“當(dāng)你看一個(gè)基于云的基礎(chǔ)設(shè)施時(shí),,通常你會(huì)使用類似Docker容器這樣的東西來部署你的工作負(fù)載。通過在Go中構(gòu)建的靜態(tài)二進(jìn)制,,你可以擁有一個(gè)10,、11、12兆字節(jié)的Docker文件,,而不是帶來整個(gè)Node.js生態(tài)系統(tǒng),,或像Python或Java那樣動(dòng)輒數(shù)百兆字節(jié)大小的Docker鏡像文件。所以,,交付那個(gè)微小的二進(jìn)制文件是很神奇的,。”——Brian Ketelsen,,微軟,。“有了Rust,我們將擁有一個(gè)高性能和可移植的平臺(tái),,我們可以輕松地在Mac,、iOS、Linux,、Android和Windows上運(yùn)行,。”——Matt Ronge,,Astropad,。在設(shè)計(jì)中,總是要做出一些取舍,。雖然Go和Rust大約在同一時(shí)間出現(xiàn),,目標(biāo)相似,但由于他們決策時(shí)選擇了不同的取舍,,使得這兩種語言在關(guān)鍵的方面有所區(qū)別,。Go開箱即有出色的性能,。在設(shè)計(jì)上,幾乎沒有預(yù)留任何旋鈕或開關(guān)可以讓你從Go中榨取更多的性能,。Rust的設(shè)計(jì)是為了讓您能夠從代碼中榨取每一滴性能;在這方面,,您確實(shí)無法找到比Rust更快的語言,。然而,Rust的性能提升是以額外的復(fù)雜性為代價(jià)的,。“值得注意的是,,在編寫Rust版本時(shí),我們只在優(yōu)化方面投入了非?;镜乃伎?。即使只做了基本的優(yōu)化,Rust的性能也能超過超手工調(diào)整的Go版本,。這極大地證明了用Rust編寫高效的程序是多么容易,,相比之下,我們不得不對(duì)Go進(jìn)行深挖,?!薄狫esse Howarth,Discord,。“Dropbox工程師通過將行對(duì)行的Python代碼移植到Go中,,往往可以看到5倍的性能提升和延遲下降,與Python相比,,內(nèi)存使用率往往會(huì)大幅下降,,因?yàn)闆]有GIL,進(jìn)程數(shù)可能會(huì)減少,。然而,,當(dāng)我們的內(nèi)存受限時(shí),比如在桌面客戶端軟件或某些服務(wù)器進(jìn)程中,,我們會(huì)轉(zhuǎn)而使用Rust,,因?yàn)镽ust中的手動(dòng)內(nèi)存管理效率大大高于Go GC?!薄狣aniel Reiter Horn,,DropboxGo快速迭代的優(yōu)勢讓開發(fā)人員可以快速嘗試各種想法,并磨合出能解決手頭任務(wù)的工作代碼,。通常情況下,,這就足夠了,可以讓開發(fā)者騰出手來處理其他任務(wù),。另一方面,,與Go相比,,Rust的編譯時(shí)間更長,導(dǎo)致迭代時(shí)間更慢,。這就導(dǎo)致了Go在一些場景中能更好地工作,,因?yàn)楦斓闹苻D(zhuǎn)時(shí)間能讓開發(fā)人員適應(yīng)不斷變化的需求,而Rust則在一些場景中茁壯成長,,因?yàn)樵谶@些場景中,,可以給予更多的時(shí)間來做出更精致、更高性能的實(shí)現(xiàn),。“Go類型系統(tǒng)的天才之處在于調(diào)用者可以定義Interface,,允許庫返回僅需滿足小接口但卻支持?jǐn)U展的結(jié)構(gòu)。Rust類型系統(tǒng)的天才設(shè)計(jì)在于匹配語法與Result<>的結(jié)合,,你可以靜態(tài)地確定每一種可能性都會(huì)被處理,,永遠(yuǎn)不必發(fā)明空值來滿足未使用的返回參數(shù)?!薄狣aniel Reiter Horn,,Dropbox“(如果)你的用例離客戶更近,更容易受到需求變化的影響,,那么用Go就會(huì)好很多,,因?yàn)槌掷m(xù)重構(gòu)的成本要便宜很多。這就是你能多快地表達(dá)新的需求并嘗試它們,?!薄狿eter Bourgon,F(xiàn)astly簡單來說,,真的沒有比Go更“平易近人”的語言了,。有很多團(tuán)隊(duì)能夠在幾周內(nèi)采用Go并將Go服務(wù)/應(yīng)用投入生產(chǎn)的故事。此外,,Go在語言中是比較獨(dú)特的,,它的語言設(shè)計(jì)和實(shí)踐在它10多年的生命中是相當(dāng)一致的。所以,,投入到學(xué)習(xí)Go上的時(shí)間可以保持很長一段時(shí)間的價(jià)值,。相比之下,Rust由于其復(fù)雜性,,被認(rèn)為是一門難學(xué)的語言,。一般來說,學(xué)習(xí)Rust需要幾個(gè)月的時(shí)間才能感覺到自如,,但這種額外的復(fù)雜性也帶來了精確的控制和性能的提高,。“當(dāng)時(shí),沒有一個(gè)團(tuán)隊(duì)成員知道Go,但在一個(gè)月內(nèi),,每個(gè)人都在用Go寫作,。”——Jaime Garcia,,Capital One“Go與其他編程語言不同的地方在于認(rèn)知負(fù)擔(dān),。你可以用更少的代碼做更多的事情,這使得你更容易推理和理解你最終編寫的代碼,。大多數(shù)Go代碼最終看起來都很相似,,所以,即使你在使用一個(gè)全新的代碼庫,,你也可以很快上手并運(yùn)行,?!薄狦len Balliet,,美國運(yùn)通忠誠度平臺(tái)工程總監(jiān),美國運(yùn)通使用Go進(jìn)行支付和獎(jiǎng)勵(lì)“然而,,與其他編程語言不同,,Go是為了最大限度地提高用戶效率而創(chuàng)建的。因此,,具有Java或PHP背景的開發(fā)人員和工程師可以在幾周內(nèi)獲得使用Go的高級(jí)技能和培訓(xùn)——根據(jù)我們的經(jīng)驗(yàn),,他們中的許多人最終都喜歡上了Go,?!薄狣ewet Diener,,Curve也許Rust最大的優(yōu)勢之一就是開發(fā)者對(duì)如何管理內(nèi)存,、如何使用機(jī)器的可用資源,、如何優(yōu)化代碼以及如何制作問題解決方案的控制,。與Go相比,,這并不是沒有很大的復(fù)雜度成本,因?yàn)镚o的設(shè)計(jì)并不是為了這種精確的制作,,而是為了更快的探索時(shí)間和更快的周轉(zhuǎn)時(shí)間,。“隨著我們對(duì)Rust經(jīng)驗(yàn)的增長,,它在另外兩個(gè)軸上顯示出了優(yōu)勢:作為一種具有強(qiáng)大內(nèi)存安全性的語言,,它是邊緣處理的好選擇,;作為一種具有巨大熱情的語言,它成為了重寫組件的流行語言,?!薄狫ohn Graham-Cumming,,Cloudflare。Go的簡單性,、性能和開發(fā)人員的生產(chǎn)力使Go成為創(chuàng)建面向用戶的應(yīng)用程序和服務(wù)的理想語言,。快速的迭代讓團(tuán)隊(duì)能夠快速地作出反應(yīng)以滿足用戶不斷變化的需求,,讓團(tuán)隊(duì)有辦法將精力集中在靈活性上,。Rust更精細(xì)的控制允許更多的精確性,使得Rust成為低級(jí)操作的理想語言,,這些低級(jí)操作不太可能發(fā)生變化,并且會(huì)從比Go略微提高的性能中受益,,特別是在非常大的規(guī)模部署時(shí)。Rust的優(yōu)勢在最接近“金屬”(指底層機(jī)器)的地方,。Go的優(yōu)勢是在離用戶更近的地方最有利,。這并不是說兩者都不能在對(duì)方的空間里工作,,但這樣做會(huì)增加摩擦。當(dāng)你的需求從靈活性轉(zhuǎn)變?yōu)樾蕰r(shí),,用Rust重寫庫的理由就更充分了,。雖然Go和Rust的設(shè)計(jì)有很大的不同,但它們的設(shè)計(jì)發(fā)揮了兼容的優(yōu)勢,,而且——當(dāng)一起使用時(shí)——既可以有很大的靈活性,,又可以有很好的性能。對(duì)于大多數(shù)公司和用戶來說,,Go是正確的默認(rèn)選擇,。它的性能很強(qiáng),Go很容易采用,,而且Go的高度模塊化特性使它特別適合需求不斷變化或發(fā)展的情況,。隨著你的產(chǎn)品逐漸成熟,需求趨于穩(wěn)定,,可能會(huì)有機(jī)會(huì)從性能的邊際增長中獲得巨大的勝利,。在這些情況下,使用Rust來最大限度地提高性能可能很值得你進(jìn)行初始投資,。
|