欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Rust 中解析 JSON的方法

 更新時間:2024年03月06日 10:09:29   作者:xuejianxinokok  
要開始在 Rust 中使用 JSON,您需要安裝一個可以輕松操作 JSON 的庫,目前可用的流行crate之一是 serde-json,在本文中,我們將討論如何在 Rust 中使用 JSON 解析庫,以及比較最流行的庫及其性能

Rust 中如何解析 JSON

在本文中,我們將討論如何在 Rust 中使用 JSON 解析庫,以及比較最流行的庫及其性能。

JSON 解析基礎(chǔ)知識

手動解析 JSON

要開始在 Rust 中使用 JSON,您需要安裝一個可以輕松操作 JSON 的庫。目前可用的流行crate之一是 serde-json 。您可以通過運(yùn)行以下命令來安裝它:

cargo add serde-json

完成后,您可以像這樣手動創(chuàng)建 JSON:

use serde_json::{Result, Value};
fn untyped_example() -> Result<()> {
    // Some JSON input data as a &str. Maybe this comes from the user.
    let data = r#" {"name":"John Doe", "age": 43, "phones": ["+44 1234567",       "+44 2345678"            ]        }"#;
    // Parse the string of data into serde_json::Value.
    let v: Value = serde_json::from_str(data)?;
    // Access parts of the data by indexing with square brackets.
    println!("Please call {} at the number {}", v["name"], v["phones"][0]);
    Ok(())
}

然而,我們可以做得更好。例如,可以將結(jié)構(gòu) 序列化為 JSON 與 或反序列化,這很常用。我們可以在 JSON 模板、Web 服務(wù)、CLI 參數(shù)等中使用它。在下一節(jié)中完成這一點(diǎn)。

使用 Serde 解析 JSON

Serde 是一個crate,可以幫助您將數(shù)據(jù)序列化和反序列化為各種格式,其中一個流行的用途是用于 JSON。如果您使用 Rust 編寫 Web 服務(wù),Serde 是您的朋友,因?yàn)槟鷮⒔?jīng)常處理可能需要發(fā)送或接收的 JSON 數(shù)據(jù)。 Serde 提供了兩個主要traits來幫助您實(shí)現(xiàn)此目的: SerializeDeserialize 。為了方便起見,添加了派生宏實(shí)現(xiàn)來幫助解決此問題。請參閱下文了解如何執(zhí)行此操作:

use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct MyStruct {
    message: String
}
fn convert_json_to_struct() {
    // create a raw JSON string from the json! macro and turn it into a MyStruct struct
    let raw_json_string = json!({"message": "Hello world!"});
    let my_struct: MyStruct = serde_json::from_str(raw_json_string).unwrap();
}

您還可以通過添加實(shí)現(xiàn) SerializeDeserialize 的結(jié)構(gòu)作為另一個也實(shí)現(xiàn) SerializeDeserialize

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>,
}

一種用例是將 JSON 嵌套在 Web 服務(wù)中。例如,當(dāng)您收到對具有 JSON 正文的 API 的 POST 請求時,您通常會將相關(guān)的 Json 類型作為處理函數(shù)參數(shù)傳遞。見下文:

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(
  // this extractor consumes a JSON body and converts it into the struct type given
    Json(json): Json<Post>
) -> Json<Post> {
  println!("{:?}", json);
    Json(json)
}

除了前面顯示如何使用 serde_json 從 JSON 字符串轉(zhuǎn)換為結(jié)構(gòu)體的代碼片段之外,您還可以從其字節(jié)表示形式轉(zhuǎn)換為結(jié)構(gòu)體:

let json_as_bytes = b" {   \"message\": \"Hello world!\",    }";
    let my_struct: MyStruct = serde_json::from_slice(json_as_bytes).unwrap();

如果您想將結(jié)構(gòu)作為字節(jié)數(shù)組存儲在某處,然后稍后將其轉(zhuǎn)回結(jié)構(gòu),那么這特別有用!

同樣,您也可以使用 .from_reader() 方法從 JSON IO 流讀取 JSON 并將其轉(zhuǎn)換為結(jié)構(gòu)體。以下是取自 serde_json 文檔的示例,說明如何將其與 TCP 流一起使用:

use serde::Deserialize;
use std::error::Error;
use std::net::{TcpListener, TcpStream};
#[derive(Deserialize, Debug)]
struct User {
    fingerprint: String,
    location: 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:4000").unwrap();
    for stream in listener.incoming() {
        println!("{:#?}", read_user_from_stream(stream.unwrap()));
    }
}

通過這種方式,您可以直接從流中反序列化,而不是在內(nèi)存中添加緩沖。如果您收到大量基于 JSON 的數(shù)據(jù),這可以為您提供很大幫助!

Comparing Rust JSON crates

比較 Rust JSON crates

盡管 serde-json 可能是最受歡迎的 crate,但它絕不是最快的。與此同時,還出現(xiàn)了一些其他 crate,以提高一般 JSON 解析性能。然而,為了換取性能,CPU SIMD 擴(kuò)展要求存在一些注意事項(xiàng)。不安全代碼的使用也有所增加,盡管一般來說,我們已盡最大努力確保代碼可以安全使用。

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

serde-json

serde-json 是最容易使用的 Rust JSON 庫。它不需要額外的依賴項(xiàng)來使用,并且當(dāng)您需要訪問原始 JSON 值的慣用操作時,通常建議與 serde 一起使用。 serde-json 還支持 no_std ,允許您關(guān)閉默認(rèn)的 std 功能并啟用 alloc

就性能而言, serde-json 本身無論如何都不慢。但是,它比此列表中的其他一些 JSON 庫慢。這主要是由于針對 非并行 CPU 使用進(jìn)行了優(yōu)化。特別是如果您能夠訪問現(xiàn)代 x86 CPU,您可能需要繼續(xù)閱讀以了解有關(guān)一些性能更好的選項(xiàng)的更多信息。然而,這個crate 也是 Rust 社區(qū)中使用最廣泛和支持最多的,所以如果您遇到問題,那么很容易找到幫助!

simd-json

simd-jsonsimdjson C++ JSON 解析器的 Rust 語言綁定,內(nèi)置了 serde 兼容性。顧名思義,該庫使用 SIMD(單指令的縮寫)多個數(shù)據(jù)。這是一種能夠通過并行處理來處理多個數(shù)據(jù)點(diǎn)的技術(shù),使其速度顯著加快!但需要注意的是,它要求您的系統(tǒng)支持 x86,并且在運(yùn)行時它將選擇最佳的 SIMD 功能集以實(shí)現(xiàn)性能。如果沒有可用的功能集,還有一個未優(yōu)化的 Rust 實(shí)現(xiàn),但在文檔中提到不應(yīng)依賴它。

文檔中提到 simd-json 可以在本機(jī)目標(biāo)編譯上滿負(fù)荷使用。您可以通過在運(yùn)行程序時啟用 rustc 中的以下編譯器選項(xiàng)來做到這一點(diǎn),如下所示:

rustc -C target-cpu=native

但是,如果您像大多數(shù)使用 Cargo 的人一樣,您可能想使用 cargo run 。如示例中所示,您可以在 .cargo/config 處創(chuàng)建配置,然后添加以下內(nèi)容:

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

一般來說,雖然這個庫相當(dāng)快,但應(yīng)該注意的是,由于它是 C++ 的 rust 語言綁定,因此該 crate 中存在相當(dāng)多的不安全代碼。這并不是說你不應(yīng)該使用它,而是要謹(jǐn)慎使用它(正如crate所說)。盡管如此,有一個關(guān)于安全的部分詳細(xì)介紹了如何堅(jiān)持最佳實(shí)踐(如單元測試)以確保crates盡可能安全地使用。

還應(yīng)該提到的是,為了獲得最佳性能,通常最好啟用 jemallocmimalloc 功能,以便能夠充分利用該庫。

一般來說, simd-json 的 API 與 serde-json 相同,因此如果您想隨時切換,那么通常這樣做不會有任何問題。

sonic-rs

sonic-rs 是具有 SIMD 功能的 JSON 操作的 Rust 實(shí)現(xiàn)。該庫還有 C++ 和 Go 中的對應(yīng)庫!雖然它過去需要 Rust nightly 工具鏈,但它支持穩(wěn)定的 Rust。與 simd-json 類似,它也需要 x86 CPU 架構(gòu)才能滿負(fù)荷運(yùn)行。

simd-json 一樣,要使用 sonic-rs 您需要在運(yùn)行程序時在 rustc 中啟用以下編譯器選項(xiàng):

rustc -C target-cpu=native

您可以在 .cargo/config 創(chuàng)建配置,然后添加以下內(nèi)容以在使用 cargo run 時啟用它:

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

這使您無需執(zhí)行任何其他操作即可構(gòu)建 SIMD!

simd-json 一樣,使用了相當(dāng)數(shù)量的 unsafe 代碼。但是,如果您在庫中搜索不安全代碼,您可能會發(fā)現(xiàn)比以前的庫中更多的 unsafe 代碼。關(guān)于如何維護(hù)不安全保證的文檔也很少,因此盡管這個庫可能比 simd-json 更快,但您需要仔細(xì)檢查是否存在未定義的行為!

sonic-rs 另外還有一些額外的方法用于惰性評估和額外的速度。例如,如果您想要 JSON 字符串文字,則可以在反序列化時使用 LazyValue 類型將其轉(zhuǎn)換為仍包含正斜杠的 JSON 字符串值。如果您不怕不安全行為或者確定它不會出錯,還有很多 unchecked 方法可以使用。

雖然 sonic-rs 是一個相當(dāng)快的庫,但它也是一個更新的 crate,因此 crate 中缺少一些方法,例如 from_reader (允許從 IO 流讀?。?。這已經(jīng)作為 GitHub 問題提出,所以希望它能盡快實(shí)施。

基準(zhǔn)

您可以在此處找到 simd-jsonserde-json 的基準(zhǔn)。 simd-jsonserde-json 相比有相當(dāng)顯著的改進(jìn)。

您可以在此處找到 sonic-rs 的基準(zhǔn),其中還將其與 simd-jsonserde-json 進(jìn)行比較。正如您所看到的,最終結(jié)果的格式與 simd-jsonserde-json 基準(zhǔn)測試的格式不同,因此每秒處理的數(shù)據(jù)量更難以理解。然而,在大多數(shù)情況下, sonic-rs 明顯(有時是巨大?。┍?simd-jsonserde-json 快。

尾聲

謝謝閱讀!我希望本文能夠幫助您了解如何有效使用 Rust JSON 解析庫。

原文地址:Parsing JSON in Rust

到此這篇關(guān)于Rust 中如何解析 JSON?的文章就介紹到這了,更多相關(guān)Rust 解析 JSON內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Rust 語言中的dyn 關(guān)鍵字及用途解析

    Rust 語言中的dyn 關(guān)鍵字及用途解析

    在Rust中,"dyn"關(guān)鍵字用于表示動態(tài)分發(fā)(dynamic dispatch),它通常與trait對象一起使用,以實(shí)現(xiàn)運(yùn)行時多態(tài), 在Rust中,多態(tài)是通過trait和impl來實(shí)現(xiàn)的,這篇文章主要介紹了Rust 語言中的 dyn 關(guān)鍵字,需要的朋友可以參考下
    2024-03-03
  • Rust中的不安全代碼詳解

    Rust中的不安全代碼詳解

    這篇文章主要為大家介紹了Rust中的不安全代碼詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Rust?語言println!?宏的格式占位符詳解

    Rust?語言println!?宏的格式占位符詳解

    這篇文章主要介紹了Rust語言的println!宏的格式占位符,這只是格式說明符的一部分清單,Rust?的格式化系統(tǒng)非常靈活和強(qiáng)大,支持更多的選項(xiàng)和組合,需要的朋友可以參考下
    2024-03-03
  • rust生命周期詳解

    rust生命周期詳解

    生命周期是rust中用來規(guī)定引用的有效作用域,在大多數(shù)時候,無需手動聲明,因?yàn)榫幾g器能夠自動推導(dǎo),這篇文章主要介紹了rust生命周期相關(guān)知識,需要的朋友可以參考下
    2023-03-03
  • 利用rust實(shí)現(xiàn)一個命令行工具

    利用rust實(shí)現(xiàn)一個命令行工具

    這篇文章主要為大家詳細(xì)介紹了如何使用?Rust?和?clap?4.4.0?創(chuàng)建一個命令行工具?my_dev_tool,文中的示例代碼講解詳細(xì),需要的小伙伴可以參考下
    2023-12-12
  • 深入了解Rust中引用與借用的用法

    深入了解Rust中引用與借用的用法

    這篇文章主要為大家詳細(xì)介紹了Rust語言中引用與借用的使用,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,需要的小伙伴可以了解一下
    2022-11-11
  • Rust如何使用config配置API

    Rust如何使用config配置API

    這篇文章主要介紹了Rust如何使用config配置API,這里記錄了如何聲明配置類型,讀取配置,通過環(huán)境變量來覆蓋配置值等開發(fā)中常見的動作,需要的朋友可以參考下
    2023-11-11
  • Rust中的模塊系統(tǒng)之控制作用域與私有性詳解

    Rust中的模塊系統(tǒng)之控制作用域與私有性詳解

    這篇文章總結(jié)了Rust模塊系統(tǒng)的基本規(guī)則,包括如何聲明模塊、路徑訪問、私有性與公開性,以及如何使用`use`關(guān)鍵字簡化路徑引用,通過一個餐廳系統(tǒng)示例,展示了如何利用模塊劃分功能,并介紹了如何在其他模塊或二進(jìn)制crate中使用這些模塊
    2025-02-02
  • Rust生命周期之驗(yàn)證引用有效性與防止懸垂引用方式

    Rust生命周期之驗(yàn)證引用有效性與防止懸垂引用方式

    本文介紹了Rust中生命周期注解的應(yīng)用,包括防止懸垂引用、在函數(shù)中使用泛型生命周期、生命周期省略規(guī)則、在結(jié)構(gòu)體中使用生命周期、靜態(tài)生命周期以及如何將生命周期與泛型和特質(zhì)約束結(jié)合,通過這些機(jī)制,Rust在編譯時就能捕獲內(nèi)存安全問題
    2025-02-02
  • C和Java沒那么香了,Serverless時代Rust即將稱王?

    C和Java沒那么香了,Serverless時代Rust即將稱王?

    Serverless Computing,即”無服務(wù)器計(jì)算”,其實(shí)這一概念在剛剛提出的時候并沒有獲得太多的關(guān)注,直到2014年AWS Lambda這一里程碑式的產(chǎn)品出現(xiàn)。Serverless算是正式走進(jìn)了云計(jì)算的舞臺
    2021-06-06

最新評論