[問題] 請問關於 Rust 跟 C 的速度比較

看板C_and_CPP作者時間8年前 (2017/08/12 13:49), 編輯推噓12(12042)
留言54則, 9人參與, 最新討論串1/2 (看更多)
最近在練習 Rust,聽說執行速度可以跟 C 相當 但看了下面網頁的執行速度比較,似乎 Rust 還是略輸一截 https://benchmarksgame.alioth.debian.org/u64q/rust.html 請問這是為什麼? 在我的粗略理解上,Rust 的很多東西都是在編譯期就處理掉了 而且因為變數的定義較為嚴格,還有可能編出較短的機械碼 那理論上應該會比 C 快才對呀? -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.41.63.59 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1502545749.A.9F5.html

08/12 22:08, , 1F
你的理論依據沒有一個可以當成比C快的理由
08/12 22:08, 1F

08/12 22:09, , 2F
應該反過來問,為何你會覺得這些會是速度比較快的原因
08/12 22:09, 2F

08/13 06:11, , 3F
雖然 rust 可以利用規則來簡化複雜的東西
08/13 06:11, 3F

08/13 06:11, , 4F
但是相反的,因為 rust 只能照規則走
08/13 06:11, 4F

08/13 06:11, , 5F
所以不在規則內的 hack 就沒辦法過 type check
08/13 06:11, 5F

08/13 09:49, , 6F
版上的教學網頁有提到
08/13 09:49, 6F

08/13 09:50, , 7F
void foo(int* x, int* y, const int* z)
08/13 09:50, 7F

08/13 09:50, , 8F
{
08/13 09:50, 8F

08/13 09:50, , 9F
*x += *z;
08/13 09:50, 9F

08/13 09:50, , 10F
*y += *z;
08/13 09:50, 10F

08/13 09:50, , 11F
}
08/13 09:50, 11F

08/13 09:51, , 12F
這樣一個函數,因為C的編譯器無法確定x、y、z是否是同一塊
08/13 09:51, 12F

08/13 09:53, , 13F
記憶體位址,而Rust的編譯器可以確定,故C編出來的機械碼會
08/13 09:53, 13F

08/13 09:54, , 14F
比Rust多一次讀取的動作,就會比較慢一點
08/13 09:54, 14F

08/13 11:10, , 15F
就說 rust 會在他知道的範圍內把東西做到最簡
08/13 11:10, 15F

08/13 11:10, , 16F
所以如果 rust 知道所有最快的 hack
08/13 11:10, 16F

08/13 11:10, , 17F
而且能夠知道同一個語意的所有不同寫法
08/13 11:10, 17F

08/13 11:10, , 18F
那理論上它會是最快的,但事實是不可能,只能盡力
08/13 11:10, 18F

08/13 11:15, , 19F
例如說,如果有一種機器,它有一個指令能夠在一個指令周
08/13 11:15, 19F

08/13 11:15, , 20F
期內做完 foo 做的事,但是 rust 不知道這個指令,或者是
08/13 11:15, 20F

08/13 11:15, , 21F
rust 不知道直接呼叫那個指令和執行這一串程式碼是相等
08/13 11:15, 21F

08/13 11:15, , 22F
的(操作語意上),那這兩個情況下 C 內嵌組語都會比 rust
08/13 11:15, 22F

08/13 11:15, , 23F
08/13 11:15, 23F

08/13 11:17, , 24F
而各個 libc 的實作都用了一大堆這種機器相關的 hack,
08/13 11:17, 24F

08/13 11:17, , 25F
所以 rust 才會這麼難超過 C
08/13 11:17, 25F

08/13 11:21, , 26F
至於為什麼我前面說不可能,第一因為這種 hack 可以有無
08/13 11:21, 26F

08/13 11:21, , 27F
限種,你隨時爽往你的機器上加什麼特性都可以
08/13 11:21, 27F

08/13 11:21, , 28F
第二因為對於所有正確的敘述,要判斷它們的語意是否相等
08/13 11:21, 28F

08/13 11:21, , 29F
,常常是 undecidable 的 (有興趣可以參考 logical seman
08/13 11:21, 29F

08/13 11:21, , 30F
tics)
08/13 11:21, 30F

08/13 11:29, , 31F
所以如果你不知道兩者語意相等,那你就沒辦法用快的取代
08/13 11:29, 31F

08/13 11:29, , 32F
慢的
08/13 11:29, 32F

08/13 11:29, , 33F
例如你上面的例子,如果 rust 不能判定少讀一次記憶體位
08/13 11:29, 33F

08/13 11:29, , 34F
址的語意是否還和原本一樣,那它就沒辦法用少讀一次的版
08/13 11:29, 34F

08/13 11:29, , 35F
本替換比較慢的版本(雖然這個 case 是可判定的)
08/13 11:29, 35F

08/13 11:33, , 36F
不知道這樣講有沒有比較清楚…
08/13 11:33, 36F

08/13 12:48, , 37F
我對樓上的解讀是,沒錯Rust比較快
08/13 12:48, 37F

08/13 15:24, , 38F
compiler和library實做完全不一樣啊...
08/13 15:24, 38F

08/13 18:37, , 39F
我想C大的例子就類似用DMA跟以byte為單位讀取資料的差別吧
08/13 18:37, 39F

08/13 18:38, , 40F
一個用一行指令就完事,一個要用for迴圈跑幾千次這樣
08/13 18:38, 40F

08/13 18:42, , 41F
Rust平常小勝,遇到可以取巧的指令大輸,結果就變成小輸
08/13 18:42, 41F

08/13 18:49, , 42F
Rust在實作上沒有取巧的空間嗎?
08/13 18:49, 42F

08/13 20:42, , 43F
@os653 可以用 restrict 提示 C Compiler 那兩個
08/13 20:42, 43F

08/13 20:43, , 44F
pointer 不會 alias 因此沒有你說的那個問題不存在
08/13 20:43, 44F

08/13 20:45, , 45F
-s 刪--xx--
08/13 20:45, 45F

08/14 01:48, , 46F
不過 restrict 只有 C99 有, C++ 因為多型的關係狀況複雜
08/14 01:48, 46F

08/14 01:48, , 47F
restrict 的語意碰上多型會有麻煩所以目前一直都沒有規定
08/14 01:48, 47F

08/14 01:49, , 48F
(連 restrict 在 C++ 都不是關鍵字)
08/14 01:49, 48F

08/14 01:50, , 49F
雖然 g++ 有提供 __restrict 給 C++ 用但我不太清楚語意
08/14 01:50, 49F

08/14 01:52, , 50F
修正一下, 是 C99 以後的 C 才有
08/14 01:52, 50F

09/18 08:09, , 51F
那個網站寫測試程式的人都盡量壓榨效能,你可以點code
09/18 08:09, 51F

09/18 08:09, , 52F
來看看,C語言的code有強大的GMP護駕 XDD
09/18 08:09, 52F

09/18 08:10, , 53F
GMP 好歹也是社區經營多年,測試結果數一數二的數學庫
09/18 08:10, 53F

09/18 08:12, , 54F
不過有好幾個測資確實無關lib,是rust比較慢
09/18 08:12, 54F
文章代碼(AID): #1PZmTLdr (C_and_CPP)
文章代碼(AID): #1PZmTLdr (C_and_CPP)