Rust高效率非同步I/O模型

banq發表於2016-08-13
Rust生態系統已經提供快速產品化的非同步I/O模型,但是過於低階,需要自己狀態機與回撥函式。現在零消耗future模型開源專案:https://github.com/alexcrichton/futures-rs釋出了,該模型是高層次抽象,能夠進行組合,其實它類似於很多語言中的future模型或promise模型,主要加入一些async/await語法糖。

所謂零消耗抽象,也就是說,不會因為提高抽象層次導致過多冗餘程式碼,這個高層次抽象編譯後等同於狀態機+回撥函式,沒有過多其他輔助程式碼,從而保證了高層次程式碼與低層次程式碼同樣的執行效率。

非同步future模型可以實現一些任務:
1.資料庫查詢
這是線上程池中執行,當查詢完成後,future完成了,它的值就是查詢結果。

2.RPC呼叫伺服器,當伺服器響應後,future完成了,它的值就是伺服器響應

3.計時,當計時時間到,future完成,它的值就是計時完成返回函式

4.長時間CPU密集任務,執行線上程池,當任務完成時,future也完成,值就是任務返回值。

5.從socket讀取位元組,當位元組準備好後,future已經完成了,依賴緩衝策略,直接返回位元組。

Rust是將future作為一個trait介面:

trait Future {
    type Item;
    // ... lots more elided ...
}
<p class="indent">


下面是幾種不同future實現:

// 根據id查詢表一行記錄,當完成查詢後yield返回該行
fn get_row(id: i32) -> impl Future<Item = Row>;

// 進行RPC 呼叫,yield返回i32
fn id_rpc(server: &RpcServer) -> impl Future<Item = i32>;

// 向TCP流寫入整個字串,當完成後yielding返回這個流。
fn write_string(socket: TcpStream, data: String) -> impl Future<Item = TcpStream>;
<p class="indent">


此外還可以使用future完成:Sequential組合;mapping;joining和selecting

使用future可以進行流處理組合:

// 對於輸入I/O 物件建立一個請求流
let requests = ParseStream::new(input);

// 對於每個請求,執行服務的`process`函式處理請求產生響應
let responses = requests.and_then(|req|service.process(req));

//建立新的future 將會把每個響應輸出到 I/O物件
StreamWriter::new(responses, output)
<p class="indent">


為了驗證零消耗抽象的future模型的高效能,使用該模型編寫的簡單 minihttp伺服器與流行的最快幾個伺服器框架比較,包括:
1.rapidoid:這是一個java框架,上一輪是最高效能
2.Go語言,使用標準HTTP庫包
3.fasthttp是Go的標準HTTP競爭者
4.Node.js

效能從高到低結果是:minihttp(Rust)、rapidoid(Java)、fasthttp(Go)、Go和node.js.

Rust高效率非同步I/O模型

原文:

Zero-cost futures in Rust · Aaron Turon

相關文章