爲什麼Rust 連續三年成爲最受歡迎的語言?

本文最初發佈於 Bitbucket 博客,經原作者 Ash Moosa 授權由 InfoQ 中文站翻譯並分享。


這是 Bitbucket 用戶 Mohit Agrawal 的客座文章,作爲 Bitbucket 寫作計劃的一部分。


爲新產品選擇編程語言是一項重要的戰略決策。它會影響很多事情,並對招聘、文化甚至產品的可行性都有長期的影響。

首先要考慮的是,你所選擇的語言對於要解決的特定問題陳述是否可行。重要的問題如下:

  • 該語言對你的特定用例是否合適?
  • 該語言能夠發揮作用嗎?
  • 該語言能夠在目標平臺上運行嗎?

這些應該是主要的問題。但也有其他因素可能會影響你的決定,比如:

  • 選擇一種特定的語言將如何影響你從理想向現實的換向時間?
  • 使用特定語言的有哪些成本優勢?
  • 解決你可能會遇到的問題有多容易?

請牢記這些問題,本文將試圖解釋我們爲新產品選擇 Rust 的原因。

用例

我們正在創建一種設備,用於使用來自各種傳感器的數據,並通過 Web 和移動應用提供實時分析和智能協助。我們需要一種足夠快的語言,以允許最小的實時延遲並使用 SoC 設備的有限資源。

下面是我們評估爲項目所選的編程語言的方法。

性能

比較實際應用的跨語言性能是一件很棘手的事情。我們在多種語言方面通常沒有同樣的專業知識,並且性能還受程序員選擇使用的算法和數據結構的影響。但是,正如以下表格的基準所示,一般認爲,Rust 的性能與 C++ 相當。並且 Rust 與其他解釋器或基於 JIT 的語言(如 Lua 或 Python)相比,性能要好得多。

語言 時間 (秒) 內存 (mb)
C++ Gcc 1.94 1.0
Rust 2.16 4.8
Java 4.03 513.8
LuaJIT 12.61 1.0
Lua 5.1 182.74 1.0
Python 314.79 4.9

來源:https://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.html

併發性

正如上面的用例所述,我們希望能夠做到實時處理來自多個傳感器的數據。我們的目標平臺 SoC 設備使用基於 ARM 的 CPU,通常有 4 個以上的內核。我們希望所有的 CPU 內核都能得到利用,這意味着擁有多線程支持非常重要。

Lua 並沒有提供原生多線程的支持。儘管有第三方的解決方案,但這些方法的性能和可靠性值得懷疑。另一方面,Rust 內置了對多線程的支持,它的所有權和借用規則幫助我們編寫出非常安全的併發代碼。

內存安全

動態類型語言提供了很大的靈活性。類型更改不需要通過程序即可進行手動傳播。它還提供了更多的思維靈活性,因爲你可以在轉換、操作和算法方面進行更多的思考。靈活性使你能夠更快地移動、更快地更改內容,並以更快的速度進行迭代。但是這些是要付出代價的。人們很容易忽略潛在的問題,而且這些問題通常很難調試。此外,這些特性往往還會帶來性能損失。

另一方面,在靜態類型語言中,在開發過程的早期階段捕獲大量錯誤,而且靜態類型通常會導致編譯代碼執行的速度更快,因爲當編譯器知道正在使用的確切數據類型時,它可以生成優化的機器代碼。靜態類型還可充當文檔。

Rust 超越了這些特點,可謂是青出於藍而勝於藍,長江後浪推前浪。Rust 非常嚴格且學究式的編譯器會檢查你使用的每個變量以及你引用的每個內存地址。它避免了可能會出現的數據競爭條件,並通知你未定義的行爲。

下圖的右側部分顯示了併發性和內存安全的問題。這些問題是最複雜的、不可預測的錯誤類別,並且從根本上來說,不可能被歸入 Rust 的安全子集。此外,所有這些類型相關的錯誤都是危險的,會導致各種安全漏洞。

image

來源:https://phil-opp.github.io/talk-konstanz-may-2018/#14

類型安全是 Rust 最大的賣點之一,也是 Rust 連續三年在 StackOverflow 調查中成爲最受歡迎的語言的原因。

Rust 實現這一效果的方式是通過使用變量所有權的概念。在 Rust 中,每個值都有一個“擁有範圍”,傳遞或返回信息意味着將所有權轉移到一個新的範圍。你可以借出對你調用的函數的訪問,這就是所謂的“借用”。Rust 確保這些租約不會超過被借用的對象的壽命。這不僅使它非常“類型安全”,而且還有助於你正面解決併發問題,因爲內存安全和併發錯誤通常會歸結爲代碼訪問數據,而實際上並不應該這樣做。

開發者體驗

Rust 有一個陡峭的學習曲線。這主要是由於我們上面討論的“所有權”和“借用”概念所致。這使得 Rust 與 Lua 或 Python 等這樣的語言相比,學習起來更困難,也更耗時。它要求開發者非常清楚關於內存分配和併發性的基本計算原則,並且還要求開發者在實現時牢記這些原則。任何語言都應該如此,尤其是在 Rust 語言中,編譯器會顯式地強制開發者編寫最佳的內存安全代碼。

儘管開發者正在使用 C++ 進行手工內存管理之類的操作,但 Rust 有很多特定和便利,這些特性和便利讓它感覺像是一種高級語言。而且 Rust 有很多抽象概念,這些抽象概念不再讓人感覺像是手動內存管理。

低級別控制和高級別安全保證了開發人員能夠對性能進行更多的控制,而無需承擔學習 C/C++ 的負擔,也不必承擔出錯的風險。

Rust 還通過其強大的庫(如 cargo test),方便了開發人員在程序內部編寫測試。與 Bitbucket 管道相結合,可以很容易地設置連續集成和可靠地發佈代碼。

結論

綜上所述,Rust 對我們的項目而言是一個很好的選擇。當你想要實現資源佔用較少的高性能併發系統時,編程語言的選擇是有限的。基於解釋器的語言在開併發性和低資源環境中往往表現不佳。系統編程語言是這種用例的理想候選語言。

但是,如果沒有資源約束,或者不需要高併發性,又或者使用其他機制(如事件循環等)實現高併發性,那麼基於解釋器的編程語言可能會更好。

C/C++ 是系統編程語言的“聖盃”。但是,在 StackOverflow 的調查中,C 和 C++ 也是最令人畏懼的語言之一,這是有原因的。對於其他高級語言的新程序員來說,接近 C/C++ 很困難。學習曲線非常陡峭。大約有 74 個不同的構建系統和由 28 個不同的包管理器組成的拼湊框架,其中大多數只支持某個平臺 / 環境,在該平臺之外是毫無用處的。經過三十多年的發展,新程序員已經投入了太多的時間和精力。

另一方面,Rust 相對來說比較容易接近,它還有一個規模相當大的社區,雖然沒有像 C/C++ 那樣的數十年的技術債務,但也提供了相對的性能。內存安全和更簡單的併發性只是附加的好處。


英文原文:
https://bitbucket.org/blog/why-rust

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章