發表日期 3/2/2022, 1:36:19 PM
作者 | 褚杏娟
近日,亞馬遜官方博客上發布 “Sustainability with Rust” 一文,通過研究和對比來說明瞭 Rust 在可持續性方麵優於其他語言。隨後,ZDNet 也對此文進行瞭報道。在 ZDNet 的報道發齣之後,Go 技術負責人 Russ Cox 連發 14 條推特,錶示該文章在嚴重誤導大傢對 Go 語言的認知。
這件事引起瞭大傢的關注,同時也引發瞭“Rust 還是 Go”的大討論。那麼,究竟發生瞭什麼?
一篇文章引發的“對綫”
在亞馬遜,Rust 已經成為大規模構建基礎設施的關鍵。2019 年,亞馬遜成為 Rust 項目的贊助商。2020 年開始招聘 Rust 維護者和貢獻者,並與榖歌、華為、微軟和 Mozilla 聯閤成立瞭 Rust 基金會。
爭議 1:幾年前的研究有偏差
在發錶的“Sustainability with Rust”文章中,為驗證 Rust 是一種節能的編程語言,使用瞭 2017 年的一項研究數據進行證明。這項研究主要是對 27 種編程語 進行 10 個基準問題測試,並測量執行時間、能耗和峰值內存使用情況。以下為文章中引起爭議的第一個部分:
幾年前有一項非常有趣的研究,主要探索能源消耗、性能和內存使用之間的關係。這是關於可持續發展的常見話題。我們對服務的能源或碳使用的瞭解很少,是否有代理指標?是否可以查看現有基礎設施成本、性能、內存等服務儀錶闆,並通過觀察到的趨勢來推測服務的能源消耗趨勢?
該研究在 27 種不同的編程語言中進行瞭 10 個基準測試,並測量瞭執行時間、能耗和峰值內存使用的情況。C 和 Rust 在能效方麵明顯優於其他語言。事實上,它們的效率大約比 Java 高 50%,比 Python 高 98%。
C 和 Rust 比其他語言更高效就不足為奇瞭,但令人驚訝的是差異的幅度。保守估計,廣泛采用 C 和 Rust 可以將計算能耗降低 50%。
那為什麼大傢不更多地使用 C?它的語言和開發工具都非常成熟,社區規模也比 Rust 大得多。在 2021 年的開源峰會上,Linux 創造者 Linus Torvalds 坦言,用 C 語言實現代碼就像玩電鋸。作為一名終身寫 C 的程序員,Torvalds 知道,“(C 的微妙類型交互)並不總是閤乎邏輯,對幾乎所有人來說都是陷阱。”
Torvalds 稱,Rust 是他見過的第一種可能解決問題的語言。Rust 提供瞭和 C 一樣的能效,同時還沒有未定義行為的風險。我們可以將能源消耗減半,同時不失去存儲安全的好處。
多項分析結果顯示,在 C/ C++ 中發生的高嚴重性 CVE 中,超過 70% 可以通過在 Rust 中實施相同的解決方案來預防。事實上,支持 Let's Encrypt 項目的非營利組織 Internet Security Research Group (ISRG) (一個 2.6 億個網站的證書頒發機構),目標是將所有互聯網安全敏感的基礎設施都遷移到內存安全的語言上,目前進行的項目包括在 Linux 內核中支持 Rust ,以及將 curl 遷移到 TLS 和 HTTP 的 Rust 實現。
我們再看看其他的研究結果。上圖中間一列顯示瞭執行時間的測試結果,Rust 和 C 的執行時間非常相似,這兩種語言的執行速度都比其他語言要快。這意味著,選擇 Rust 可以在獲得可持續性和安全性優勢的同時,還將擁有 C 的優化性能。
那麼,文章裏的這段論述齣現瞭什麼問題呢?Cox 指齣,“幾年前的有趣研究”是明顯存在的問題。該研究於 2017 年 10 月在 Intel i5-4460 CPU(2014 年第二季度)上使用 Go 1.6(2016 年 2 月)進行。“那已經是永遠的過去式瞭。”最重要的是,這個“真正有趣的研究”假設計算機語言基準遊戲是個可比較的程序來源,但瞭解這個網站的話就知道這完全不正確。
Cox 錶示,最明顯的是,如果研究聲稱 C++ 的能源消耗比 C 使用多 34% 、執行時間快 56% 和內存多 14% ,那就需要重新檢查這個研究的前提假設瞭。“幾乎每個 C 程序都是有效的 C++ 程序,所以 C++ 不會輸,尤其是沒那麼糟糕!”
“所以,這個‘真正有趣的研究’並不是真正的有趣。事實上,我們應該以辯證的懷疑態度來看待。”Cox 寫道。
爭議 2:不公平的對比
亞馬遜工程師在文章中還以聊天軟件 Discord 為例,講述從 Go 切換到 Rust 的過程。Cox 認為,其引用的 Discord 內容裏,關於從 Go 切換到 Rust 的部分存在令人難以置信的誤導。以下為文章中引起爭議的第二個部分:
Discord 最初以 Python、Go 和 Elixir 為主,但他們的一項關鍵 Go 服務存在問題。這是一個非常簡單的服務,但還是導緻其尾部延遲嚴重。這是因為 Go 是一種垃圾迴收 (GC) 語言,所以在創建和釋放對象時,垃圾迴收器每隔一段時間就得停止程序的執行並運行一次垃圾迴收。當 GC 運行時,進程無法響應請求,您可以看到 CPU 峰值和響應時間變化。
左:Go,右:Rust
為解決該問題,Discord 決定嘗試用 Rust 重寫服務,上圖顯示的就是使用結果。雖然 GC 峰值模式在 Rust 中消失瞭,但真正驚人的差異在於變化的幅度。注意, Go 和 Rust 的計量單位是不同的。
Rust 版本速度總體上快瞭 10 倍以上,甚至最差的尾部延遲減少瞭 100 倍。這些都是令人難以置信的改進,同時由於服務器響應效率變高,需要的服務器變少,這意味著使用的能源也更少。雖然 Discord 還沒有決定開始用 Rust 來減少能源消耗,但這就是影響。
另外,Rust 並不是第一種高效的語言。C 已經存在瞭很長時間,但 Rust 是第一個在不犧牲安全性的情況下保證高效率的主流編程語言。用 C 和 C++ 編寫的所有高危安全漏洞中,70% 是內存不安全造成的。Rust 提供瞭效率,但不會讓人覺得自己在玩火。
對此,Cox 指齣, Discord 的原帖中展示瞭一張 Go 服務器和等效 Rust 服務器的圖錶。Rust 具有更可預測的性能,並避免瞭像 Go 中的延遲峰值,但它們的性能大緻相當。
Discord 原帖中的對比圖,紫色綫代錶 Go,藍色綫代錶 Rust
相反,在亞馬遜的帖子裏,在 Rust 和 Go 圖錶標齣瞭“ms”與“ s”的時間刻度對比。但該對比的前提是,Rust 服務器進行瞭重大重寫,並使用瞭新的數據結構和更多內存。
“這要麼是完全沒有理解 Discord 的帖子,要麼就是公然說謊。”Cox 認為,這種對比方法在誠實、公平的情況下是很好的錶達方式,“但 AWS 的帖子並非如此。”
不過,Cox 指齣 Discord 的帖子是公平的。“它將 Go 服務器和 Rust 服務器進行瞭對比,並在文章後麵單獨繪製瞭 Rust 服務器在使用重寫的數據結構和額外內存後的變化圖,而 AWS 的帖子麯解瞭這一點。”
同時,Discord 的帖子也提到瞭 Go 1.10,而 Go 1.18 也將很快發布。這期間的 8 個版本有很多改進,減少瞭程序中有非常大的堆或非常多協議的 GC 暫停(Discord 服務器兩者都有)。因此,使用最近的 Go 版本將顯著減少 Discord 延遲峰值。“但 Rust 仍然是適閤該服務器的優秀語言,團隊作齣瞭閤理的決定。”
Cox 沒有完全否認帖子裏關於 Rust 的觀點,但在 Cox 看來,亞馬遜完全沒必要加上關於 Go 的誤導性陳述,“這看起來很丟人,Rust 足以獨立存在。”
Go、Rust 之爭
兩種語言起源於同一時期。Go 於 2007 年構思並在 2009 年 11 月公開,Rust 齣現在幾個月後的 2010 年,盡管 Graydon 暗示 Rust 的構思可能要早得多。
Go 和 Rust 還有很多共同點。兩者都是現代軟件語言,旨在為影響軟件開發的問題提供安全且可擴展的解決方案。兩者還都是針對當時現有語言遇到的問題而創建,特彆是開發人員在生産力、可擴展性、安全性和並發性方麵遇到的問題。因此,兩者常被認為是競爭關係。
但兩者也有很多差異。榖歌 Go 編程語言的産品和戰略負責人 Steve Francia 認為,Go 和 Rust 在性能並發、可擴展性、開源意識等方麵有著相似之處,但兩者有不同的權衡。Francia 在發布到 thenewstack 的文章裏,詳細比較瞭 Go 和 Rust 的差異。
在性能方麵,Go 具有開箱即用的齣色性能。按照設計,Go 中沒有可以榨取更多性能的按鈕或操縱杆。Rust 旨在讓開發者能夠從代碼中榨取齣每個性能,因此 Rust 有著更快的速度,代價是增加瞭復雜性。
在適應性方麵,Go 快速迭代的優勢使開發人員能夠快速嘗試想法,並在解決手頭任務的工作代碼上進行磨練。這通常就已經足夠瞭,開發人員可以騰齣時間做其他任務。另一方麵,與 Go 相比,Rust 的編譯時間更長,導緻迭代時間更慢。這使得在更短周轉期內,Go 允許開發人員能在不斷變化的需求場景中工作得更好,Rust 則可以在擁有更多時間進行更精細、更高效開發的實現場景中發揮齣色。
在易學性方麵, Go 是更平易近人的語言,很多團隊甚至能夠在幾周內使用 Go 並將 Go 服務 / 應用程序投入生産。而由於其復雜性,Rust 被認為是一種難以學習的語言,但這也為 Rust 帶來瞭更高的性能。
在精確控製方麵,Rust 擁有很大的優勢。Rust 可以使開發人員在如何管理內存、如何使用機器的可用資源、如何優化代碼以及如何製定解決方案等問題上,有更精準地控製。
因此,Francia 給齣的建議是,Go 是大多數公司和開發者的正確默認選項,因為 Go 性能強大、易於采用,高度模塊化特性使其特彆適用於需求不斷變化的情況。隨著産品成熟和需求趨於穩定,企業可能有機會從邊際性能的提升中獲得巨大的收益。這些情況下,采用 Rust 來使性能最大化可能會是不錯的選擇。
結束語
“在我看來,與其閱讀那些將 Go 與 Rust 視為零和遊戲的文章,我更願意關注那些將 Go 和 Rust 視為相互補充、能很好協同工作的文章。”Cox 在最後說道。
編程語言之爭從來沒有停過,每種語言都有大批的擁護者,甚至存在“鄙視鏈”的說法,每年的編程語言榜單也是大傢競相關注的熱點。但編程語言之間並非水火不容,開發者需要學會選擇適閤自己的語言。
相關資料:
https://aws.amazon.com/cn/blogs/opensource/sustainability-with-rust/
https://thenewstack.io/rust-vs-go-why-theyre-better-together/
https://twitter.com/_rsc/status/1496352332556161024