自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

為什么不用Rust?

開發(fā) 后端
最近我讀了一篇批評 Rust 的文章,雖然它提出了一堆好的觀點,但我并不認同它 -- 這是一篇容易引起爭論的文章??偟膩碚f,我不會推薦一篇批評 Rust 的文章。

[[343803]]

最近我讀了一篇批評 Rust 的文章,雖然它提出了一堆好的觀點,但我并不認同它 -- 這是一篇容易引起爭論的文章??偟膩碚f,我不會推薦一篇批評 Rust 的文章。這是一個遺憾 -- 正視缺點是很重要的,但也需要反對那些草率的或者不準確失誤的批判。

所以,下面是我力挺 Rust 的一些理由。

不是所有的開發(fā)都是系統(tǒng)編程

Rust 是一種系統(tǒng)編程語言。它提供了對數(shù)據布局和代碼運行時行為的精確控制,賦予你最大的性能和靈活性。與其他系統(tǒng)編程語言不同的是,它還提供了內存安全--有bug的程序會以一種明確定義的方式終止,而不是出現(xiàn)(潛在的安全威脅)未定義的行為。

然而,在大多數(shù)情況下,人們并不需要終極性能或對硬件資源的極致控制。在這種情況下,像 Kotlin 或 Go 這樣的現(xiàn)代可管理語言提供了不錯的速度和令人羨慕的性能,并且由于使用垃圾回收器進行動態(tài)內存管理而保證了內存安全。

復雜度

程序員的時間是寶貴的,如果你選擇了 Rust,預計會有一部分時間花在學習各種使用技巧上。Rust 社區(qū)傾注了大量的時間來創(chuàng)建各種高質量教程,但 Rust 語言很龐大。即使 Rust 能夠為你提供價值,你也可能沒有太多精力投入到語言專業(yè)知識的提升中。

Rust 提高控制力的代價是選擇的魔咒。

  1. struct Foo     { bar: Bar         } 
  2. struct Foo<'a> { bar: &'a Bar     } 
  3. struct Foo<'a> { bar: &'a mut Bar } 
  4. struct Foo     { bar: Box<Bar>    } 
  5. struct Foo     { bar: Rc<Bar>     } 
  6. struct Foo     { bar: Arc<Bar>    } 

在 Kotlin 中,你開始 class Foo(val bar: Bar),就可以繼續(xù)解決你的業(yè)務問題了。在 Rust 中,你需要做出一些選擇,有些重要到需要專門的語法。

所有這些復雜性的存在是有原因的 -- 我們不知道如何創(chuàng)建一個更簡單的內存安全的低級語言,雖然并不是每個任務都需要用低級語言來解決。

另請參見《為什么C++在瓦薩號沉沒時航行》。

https://www.youtube.com/watch?v=ltCgzYcpFUI

編譯時間

編譯時間是所有工作的倍數(shù)。用運行速度較慢但編譯速度較快的編程語言編寫的代碼,可以有機會運行得更快,因為程序員可以有更多的時間去優(yōu)化代碼。

Rust 在通用性的難題中有意挑選了慢速編譯器。這并不一定是世界末日(因為由此帶來的運行時性能提升是實實在在的),但這確實也意味著在大型項目中,你將不得不為合理的構建時間而拼盡全力。

rustc 實現(xiàn)了可能是生產型編譯器中最先進的增量編譯算法,但這感覺有點像和語言編譯模型打架。

https://rustc-dev-guide.rust-lang.org/queries/incremental-compilation.html

與 C++ 不同的是,Rust 的構建并不是尷尬的并行,并行的數(shù)量受限于依賴圖中關鍵路徑的長度。如果你有40多個 core 進行編譯,這就會體現(xiàn)出來。

Rust 還缺少一個類似于 pimpl 的功能,這意味著改變一個 crate 需要重新編譯(而不僅僅是重新鏈接)其所有的反向依賴。

pimpl 見: https://en.cppreference.com/w/cpp/language/pimpl

成熟度

只有 5 歲,Rust 絕對是一門年輕的語言。盡管它的前景燦爛,但我曾經在“C將在十年后存在”上下的賭注,要比“Rust 將在十年后存在”下的賭注多得多(參見 Lindy Effect)。如果你寫的軟件要持續(xù)幾十年,你應該認真考慮選擇新技術的相關風險。但請記住,90年代在銀行軟件上選擇 Java 而不是 Cobol,回想起來,證明是無比正確的選擇)。

Lindy Effect: https://en.wikipedia.org/wiki/Lindy_effect

Rust 目前僅有一個完整的實現(xiàn) -- rustc 編譯器。另一個最好的替代實現(xiàn) mrustc,故意省略了許多靜態(tài)安全檢查。rustc 目前只支持一個生產就緒的后端 -- LLVM。因此,它對 CPU 架構的支持比 C 窄,C 架構有 GCC 實現(xiàn),也有許多廠商特定的專有編譯器。

最后,Rust 缺乏官方規(guī)范。參考文檔是一個正在進行中的工作,還沒有記錄所有細致的實現(xiàn)細節(jié)。

可替代性

在系統(tǒng)編程領域,除了 Rust 之外,還有一些其他語言,主要有 C、C++ 和 Ada。

現(xiàn)代 C++ 提供了提高安全性的工具和準則。甚至有人提議建立類似 Rust 的生命周期機制。與 Rust 不同,使用這些工具并不能保證沒有內存安全問題。然而,如果你已經維護了大量的 C++ 代碼,那么檢查一下遵循最佳實踐和使用 sanitizer, 對于解決安全問題是有意義的。這很難,但顯然比用另一種語言重寫更容易。

如果你使用 C 語言,你可以使用形式化方法來證明沒有未定義的行為,否則你只能詳盡地測試一切。

Ada 是內存安全的,如果你不使用動態(tài)內存(永遠不調用 free)。

Rust 是成本/安全曲線上的一個有趣的點,但肯定不是唯一的一個點。

工具

Rust 工具是值得稱贊的東西。基線工具、編譯器和構建系統(tǒng)(cargo),經常被認為是一流的。

但是,舉例來說,一些與運行時相關的工具(最明顯的是堆分析)目前還不存在 -- 如果沒有運行時工具,就很難對程序運行時進行分析。此外,雖然 IDE 的支持還算不錯,但遠沒有達到 Java 級別的可靠性。如今在 Rust 中,數(shù)百萬行程序的自動復雜重構還做不到。

集成

不管 Rust 的愿景是什么,今天的系統(tǒng)編程世界還是 C 和 C++ 的天下,這是一個事實。Rust 有意不試圖模仿這些語言 —— 它沒有使用 C++ 風格的類或 C ABI。

這意味著,它們之間的集成需要明確的橋梁。這些都不是無縫的。它們是不安全的,并不總是零成本的,并且需要在語言之間同步。雖然片斷式集成的一般也還能維持,工具也能趕上,但一路上卻意外的復雜。

一個具體的小麻煩是,Cargo 獨特的世界觀(這對純 Rust 項目來說是個福音)可能會使它更難與更大的構建系統(tǒng)集成。

性能

"使用LLVM" 并不是解決所有性能問題的通用方案。雖然我不知道 C++ 和 Rust 在規(guī)模上的性能的基準,但不難列出一個 Rust 不如 C++ 一些性能問題列表。

最大的一個可能是 Rust 的 move 語義是基于 value 的(機器代碼級別的 memcpy)。相比之下,C++ 語義使用的是你可以使用數(shù)據的特殊引用(機器代碼級的指針)。理論上,編譯器應該能夠看穿復制鏈,但在實踐中往往不能。#57077. 一個相關的問題是沒有放置 new -- Rust 有時需要從堆棧中復制字節(jié),而 C++ 可以在原地構造東西。

57077 https://github.com/rust-lang/rust/issues/57077

有點有趣的是,Rust 的默認 ABI(為了使其盡可能高效,它并不穩(wěn)定)有時比 C 更差。#26494.

https://github.com/rust-lang/rust/issues/26494#issuecomment-619506345

最后,雖然理論上 Rust 代碼應該更高效,因為有更豐富的別名信息,但啟用別名相關的優(yōu)化會引發(fā) LLVM bug 和誤編譯。#54878.

https://github.com/rust-lang/rust/issues/54878

但是,重申一下,這些都是挑出來的例子,有時候這些領域會有相反的情況。例如,std::unique_ptr 的性能問題在 Rust 的 Box 中就不存在。

一個潛在的更大的問題是,Rust 的定義時間檢查的泛型,表現(xiàn)力不如 C++。所以,一些高性能的 C++ 模板技巧,在 Rust 中就很難用漂亮的語法來表達。

模板技巧 http://eigen.tuxfamily.org/index.php?title=Expression_templates

Unsafe 的定義

一個比所有權和借用更核心的問題也許是 unsafe 的邊界。通過在 unsafe 的塊和函數(shù)后面劃定所有危險的操作,并為它們提供安全的上層接口,就有可能創(chuàng)建一個既是:

  • 合理的(非不安全的代碼不能導致未定義行為)。
  • 和模塊化 (不同的不安全塊可以分別檢查)。

很明顯,這個承諾在實踐中得到了驗證:有問題的 Rust 代碼會帶來 panic,而不是緩沖區(qū)超限。

但在理論上來看,問題就不那么樂觀了。

首先,沒有 Rust 內存模型的定義,所以無法正式檢查給定的不安全塊是否有效。有非正式的 "rustc 所做的或可能依賴的事情 "的定義,并且在進行中的運行時驗證器,但實際的模型是在變化的。所以可能有一些不安全的代碼,今天在實踐中還可以用,明天可能就被宣布無效,明年又被新的編譯器優(yōu)化打破。

其次,還有一個觀察,不安全塊其實不是模塊化的。足夠強大的不安全塊實際上可以擴展語言。兩種這樣的擴展單獨使用可能是好的,但如果同時使用會導致未定義的行為,觀測等價性和不安全代碼。

見: https://smallcultfollowing.com/babysteps/blog/2016/10/02/observational-equivalence-and-unsafe-code/

最后,編譯器中存在 bug。

見:https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3A%22I-unsound+%F0%9F%92%A5%22

下面是我刻意忽略的一些東西。

  • 經濟學:("雇用 Rust 程序員很難了")--我覺得 "成熟度 "部分抓住了它的本質,它不能還原成雞和蛋的問題。
  • 依賴性:("stdlib太小/所有東西都有太多的依賴")-- 考慮到 Cargo 和語言的相關部分有多好,我個人不認為這是一個問題。
  • 動態(tài)鏈接:("Rust 應該有穩(wěn)定的ABI")--我不認為這是一個強有力的論點。單態(tài)化與動態(tài)鏈接在根本上是很不兼容的,如果真的有需要,還有 C ABI 可用。我確實也認為這里有可改善空間,但我不認為這種改善需要針對 Rust。見:https://internals.rust-lang.org/t/a-stable-modular-abi-for-rust/12347/10?u=matklad

英文原文:

https://matklad.github.io/2020/09/20/why-not-rust.html

本文轉載自微信公眾號「高可用架構」,可以通過以下二維碼關注。轉載本文請聯(lián)系高可用架構公眾號。

 

責任編輯:武曉燕 來源: 高可用架構
相關推薦

2023-06-06 09:03:06

InnodbMySQL

2020-06-19 14:55:11

Kubernetes容器技術

2021-02-24 07:42:34

PythonRust語言

2024-08-28 10:49:47

2019-03-11 08:36:11

Python代碼Flask

2021-05-06 06:53:39

DockerGoogleFacebook

2019-05-15 08:29:56

Web面板運維

2009-12-14 18:27:21

Linux操作系統(tǒng)

2015-01-08 15:18:43

DockerDockerFile創(chuàng)建鏡像

2024-02-05 22:51:49

AGIRustPython

2020-07-08 09:30:29

Python編程語言終止符

2023-03-10 08:48:29

2015-11-17 08:54:42

語言gorust

2015-11-17 10:00:50

DGORust

2015-07-13 10:27:40

GoRust競爭者

2025-03-25 07:10:00

開發(fā)前端JavaScript

2020-08-07 14:24:34

諾基亞安卓塞班系統(tǒng)

2009-07-07 17:18:57

Facelets介紹JSP與Facelet

2024-11-04 09:26:42

RESTJavaAPI

2018-10-11 15:51:32

ChromeGoogle瀏覽器
點贊
收藏

51CTO技術棧公眾號