日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

sonic-rs ?還具有一些額外的方法來進行惰性評估和提高速度。例如,如果我們想要一個 JSON? 字符串文字,我們可以在反序列化時使用 LazyValue? 類型將其轉換為一個仍然帶有斜杠的 JSON 字符串值。如果我們不怕不安全行為,或者確信它不會出錯,還有很多未經檢查的方法可供我們使用。

前言

我們之前在Rust 賦能前端-開發一款屬于你的前端腳手架中有過在Rust項目中如何操作JSON。

圖片圖片

由于文章篇幅的原因,我們就沒詳細介紹這塊的內容,而今天我們就抽空聊聊這個話題。-- 「如何在Rust中操作JSON,以及對最流行的庫進行比較」

好了,天不早了,干點正事哇。

我們能所學到的知識點

  1. 操作JSON數據
  2. 比較 Rust 的 JSON crates

1. 操作JSON數據

創建JSON數據

要在Rust中處理JSON,我們可以借助相關的JSON庫。其實市面上有很多相關的庫,但是我們還是選擇一種我們比較熟悉并且流行度高的庫。--serde-json[1]

我們可以通過運行以下命令來安裝它:

cargo add serde-json

完成后,我們可以像這樣手動創建JSON:

use serde_json::{Result, Value};

fn untyped_example() -> Result<()> {
    // 一些JSON輸入數據,作為一個&str。也許這些數據來自用戶。
    let data = r#"
        {
            "name": "Front789",
            "age": 18,
            "ability": [
                "Front-end development",
                "Rust",
                "AI"
            ]
        }"#;

    // 將數據字符串解析為serde_json::Value。
    let v: Value = serde_json::from_str(data)?;

    // 通過使用方括號索引來訪問數據的部分。
    println!("我是{}。一個專注于{}/{}及{}應用知識分享**的Coder", 
    v["name"], v["ability"][0],v["ability"][1],v["ability"][2]);

    Ok(())
}

然而,我們可以做得比這更好。例如,我們可以將JSON序列化為結構體,這在許多應用中都有用途。我們可以在JSON模板、Web服務、CLI參數(這點我們的f_cli[2]就使用了它)等方面使用它。

當然,我們也可以使用std::fs::write來將這些JSON數據寫入到磁盤文件中。

使用Serde解析JSON

Serde是一個crate,它幫助我們將數據序列化和反序列化為各種格式,其中一個流行的用途是用于JSON。Serde提供了兩個主要的trait來幫助我們完成這一點:Serialize和Deserialize。我們可以添加了一個派生宏實現來幫助我們完成這一點。

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
pub struct MyStruct {
    message: String
}

fn convert_json_to_struct() {
    // 從json!宏創建一個原始的JSON字符串,并將其轉換為MyStruct結構體
    let raw_json_string = json!({"message": "Hello Front789!"});
    let my_struct: MyStruct = serde_json::from_str(raw_json_string).unwrap();
}

我們還可以創建「嵌套的JSON」,方法是將實現Serialize和Deserialize的結構體作為另一個也實現Serialize和Deserialize的結構體的字段:

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
pub struct Post {
    nested_json: PostMetadata,
    title: String,
    body: String
}

#[derive(Serialize, Deserialize)]
pub struct PostMetadata {
    timestamp_created: DateTime<Utc>,
    timestamp_last_updated: DateTime<Utc>,
    categories: Vec<String>,
}

上面的代碼可以用于我們用Rust創建一個Web服務(還記得我們之前介紹過的Rust Web 開發之Axum使用手冊嗎),并且返回一個嵌套JSON。例如,當我們的Web服務器收到一個POST請求,其Body中是一個Json數據時,我們通常會將相關的Json類型作為處理程序函數的參數傳遞。

use axum::Json;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
pub struct Post {
    nested_json: PostMetadata,
    title: String,
    body: String
}

#[derive(Serialize, Deserialize)]
pub struct PostMetadata {
    timestamp_created: DateTime<Utc>,
    timestamp_last_updated: DateTime<Utc>,
    categories: Vec<String>,
}

async fn receive_some_json(
  // 這個提取器消耗一個JSON主體,并將其轉換為給定的結構類型
    Json(json): Json<Post>
) -> Json<Post> {
    println!("{:?}", json);
    Json(json)
}

我們還可以從其字節表示形式轉換為結構體:

let json_as_bytes = b"
        {
            "message": "Hello Front789!",
        }";

    let my_struct: MyStruct = serde_json::from_slice(json_as_bytes).unwrap();

上面的處理方式,在我們想將一個結構體存儲在某個地方作為字節數組,然后再將其轉換回結構體時,有奇特的效果!

類似地,我們還可以從JSON的「IO流」中讀取JSON并將其轉換為結構體,使用.from_reader()方法。以下代碼中展示了如何在TCP流中使用它:

use serde::Deserialize;
use std::error::Error;
use std:.NET::{TcpListener, TcpStream};

#[derive(Deserialize, Debug)]
struct User {
    name: String,
    age: String,
}

fn read_user_from_stream(tcp_stream: TcpStream) -> Result<User, Box<dyn Error>> {
    let mut to_be_deserialized = serde_json::Deserializer::from_reader(tcp_stream);
    let user = User::deserialize(&mut to_be_deserialized)?;

    Ok(user)
}

fn main() {
    let listener = TcpListener::bind("127.0.0.1:7890").unwrap();

    for stream in listener.incoming() {
        println!("{:#?}", read_user_from_stream(stream.unwrap()));
    }
}

這樣,當我們在遇到需要處理JSON的數據時,我們就可以直接從流中反序列化,而不是在內存中添加緩沖區。

2. 比較 Rust 的 JSON crates

其實,在大部分情況下,serde-json已經能夠滿足我們的需求了。但是,在一些特殊情況下,例如數據量過大,此時serde-json就有點吃力了。所以,市面上又有了一些提高 JSON 解析性能的crate。(simd-json/sonic-rs)

圖片圖片

從上圖可知serde-json有碾壓式優勢,也就是不到萬不得已,我們還是使用serde-json。不過,本著知己知彼,方能百戰不殆。我們也需要知曉額外的解決方案。

這些 crates 大部分具有相同的 API。除非另有說明,否則我們可以安全地在這些庫之間切換,并期望在每個庫中使用 JSON 時具有大致相同的接口。

serde-json

serde-json 是 Rust 中下載和使用最多的 JSON 庫之一。

就性能而言,serde-json 本身并不慢。然而,然后對比其他兩個crate就有點稍遜了。這主要是因為它被采用非并行化的 CPU 使用架構。這樣的話,serde-json就無法在x86 CPU的系統架構上,發揮更強的作用。

x86 是一種廣泛使用的中央處理單元 (CPU) 計算機架構。它已成為個人計算機和服務器的主導架構。x86這個名稱源自 8086,這是英特爾® 發布的早期處理器。x86 CPU 使用「復雜指令集計算機」 (CISC) 設計,允許它們在「單個周期內執行多條指令」。x想了解更多關于x86 CPU的內容,可以參考x86介紹[3]

simd-json

simd-json[4] 是 simdjson C++ JSON 解析器的 Rust 版本,內置了 serde 兼容性。正如其名稱所示,此庫使用 SIMD(單指令多數據)。這是一種用于能夠使用并行處理處理多個數據點的技術,使其速度顯著更快!然而,作為一個注意事項,它要求我們的系統具有 x86 能力,并且在運行時會選擇最佳的 SIMD 特性集以獲得性能。

文檔中提到 simd-json 可以在本機目標編譯時充分發揮作用。我們可以通過在運行程序時啟用 rustc 中的以下編譯器選項來實現此目標,例如:

rustc -C target-cpu=native

然而,如果我們像大多數使用 Cargo 的人一樣,我們可能想使用 cargo run。與示例中一樣,我們可以在 .cargo/config 中創建一個配置,然后添加以下內容:

[build]
rustflags = ["-C", "target-cpu=native"]

在.cargo/config配置相關的內容,我們在Rust交叉編譯windows環境時候,也涉及到。

[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"

一般來說,盡管這個庫非常快,但應該注意到這個 crate 中有相當多的不安全代碼,因為它是 C++ crate 的一個移植。這并不意味著我們不應該使用它,而是要謹慎使用。

還應該提到的是,為了獲得最佳性能,通常最好啟用 jemalloc 或 mimalloc 特性,以充分利用庫。

通常情況下,simd-json 的 API 與 serde-json 相同,因此如果我們想在任何時候切換,通常不應該遇到任何問題。

sonic-rs

sonic-rs[5] 是具有 SIMD 功能的 JSON 操作的 Rust 實現。這個庫還有一個 C++ 和 Go 的對應庫!盡管它曾經需要 Rust nightly 工具鏈,但現在支持穩定的 Rust。與 simd-json 類似,它也需要 x86 CPU 架構才能充分發揮作用。

與 simd-json 一樣,要使用 sonic-rs,我們需要在運行程序時啟用 rustc 中的以下編譯器選項:

rustc -C target-cpu=native

我們可以在 .cargo/config 中創建一個配置,然后添加以下內容以在使用 cargo run 時啟用它:

[build]
rustflags = ["-C", "target-cpu=native"]

這樣我們就可以構建支持 SIMD 的程序而無需做其他操作!

與 simd-json 類似,這個庫中使用了相當多的不安全代碼。然而,如果我們在庫中搜索不安全代碼,我們會發現比之前的庫中的不安全代碼可能更多。

sonic-rs 還具有一些額外的方法來進行惰性評估和提高速度。例如,如果我們想要一個 JSON 字符串文字,我們可以在反序列化時使用 LazyValue 類型將其轉換為一個仍然帶有斜杠的 JSON 字符串值。如果我們不怕不安全行為,或者確信它不會出錯,還有很多未經檢查的方法可供我們使用。

盡管 sonic-rs 是一個非常快的庫,但它也是一個較新的 crate,因此某些方法,如 from_reader(允許從 IO 流讀取)在 crate 中缺失。

Reference

[1]

serde-json:https://crates.io/crates/serde_json

[2]f_cli:https://www.npmjs.com/package/f_cli_f

[3]x86介紹:https://www.lenovo.com/us/en/glossary/x86/

[4]simd-json:https://crates.io/crates/simd-json

[5]sonic-rs:https://crates.io/crates/sonic-rs

分享到:
標簽:Rust
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定