前置き: serde-json
を使おうとしなかった理由最終週は、Mastodon と Fediverse の原動力となっているプロトコルである ActivityPub の探索に取り掛かります。 JSON ペイロードによく使用される構造 (JSON-LD Compacted Document Comprise) を使用します。 簡単な ActivityPub の演習では、次のように記述できます: { "@環境": "https://www.w3.org/ns/activitystreams"、 "形": "切手"、 "に": 、 "に起因する ": "https ://social.instance/alyssa/", "言いたいこと
": "司令官、私はその本を読むことができましたか" }
@context
) 領域は非常に重要です。ドキュメントの快適さがどのように解釈されるかを制御します。 達成すべき明確な問題の 1 つは、ドキュメントのスキーマを拡張することです: { "@環境": { "@vocab": "https://www.w3.org/ns/ activitystreams", "ext": "https://dogs-extension.instance/phrases/
", "@言語": "en
" }、 "まとめ": "ショー"、 "形": "切手", "材料を言う": "私の犬にはノミがいます.
」、「内線:鼻孔": 0、"ext:scent": "不快" }
何区ごとに非公開にネーム システムでは、@context
を参照する必要があります。 この状況では、ext:nostril
は実際には ext で定義された nostril
です。 https://dogs-extension.instance/phrases/
にある語彙。 それにもかかわらず、 ext
の使用法は完全に恣意的です。 私が意識している限りでは、Serde からの構文解析におけるこの柔軟性に対処する有能な機能として、このようなものはもはや存在しないでしょう。 現在、ActivityPub/JSON-LD 関連のクレートがいくつかありますが、特定の原因には立ち入らずに、自分の開発した実装を突き刺す必要がありました。 経験上、serde_json::Cost
は借用したファイルを保存できないことを知っていました。 私のユースケースでは、すべての文字列に約 1 分の割り当てを合理的に望むよりも、一度解析した JSON からファイルを借りることができるクレートを回収する必要がありました。 JSONのすべてのオブジェクトキーは文字列なので、それらは急速に加算されます.クレートを見つけるのは面倒です
私は、自分のニーズに合ったクレートを求めて、すべての lib.rs と crates.io を試すのに時間を費やしました。 ロード の JSON パーサーが取得可能です。 そして、それらの主な好みは、入力からファイルを借用することもできなくなります. JSON があまり洗練されていないことはわかっていたので、beget を実際に作成することは明らかでした。 Reddit にスレッドがポップアップ表示され、多くの貴重なリソースを発見しました:
)Serdeのjson-benchmark
、次にクレートを置くと:serde-json
json
simd-json
rustc-serialize
(非推奨/アーカイブ済み) json-deserializerへのアドバイス
両方を推奨するフィードバック simd-json
または json
これらの最新のリソースを使用して、私は感じましたbeget の実装で時間を無駄にしてしまったのはばかげています。 私は夜の快適さのためにリラックスし、json
朝のクレート.Rust JSON エコシステムではすべてが OK ではなくなります json
クレート 、もう少し注意する必要がありました。 2020 年 3 月 18 日に最後の自由化が行われます。JSON は非常に小さな構造であるため、これは必ずしも本質的に心配する必要はありません。 それは JSONクレートが達成するために実行可能です安定性が向上し、追加の変更は不要になりました。 たとえそれが一度でも起こったとしても、過去 3 年間で 1.0 をある程度解放しないのはなぜですか? さらに、crates.io リストに README がないのはなぜですか? Github ポイントで両方のリクエストをリクエストした個人がいるかどうかは明らかです。 代わりに、私は ユーザーがベンチャーが一度見捨てられたものになるかどうかを尋ねているのを見ました。 さらに、一度報告された未定義の動作の危険性のように見えるものを見ました 2021 年 2 月 1 日 に、コメントまたは対処されていないシステムによって一度になります。 Miri でエラーを引き起こすコードがよそよそしいことを確認しました。この特定のクレートについてフレーズが展開されたかったように感じました。 ほぼ毎日ダウンロードされます。 セキュリティ勧告を提出しました) (完全に破損した監査に申し訳ありません!) および という危険性json-benchmark ベンチャー。 それで json-deserializer
、もう 1 人のコメンターが一度提案する合理的に支持された解説で? 自分のbegetライブラリを試してみてから )json.org JSON チェッカーのスイート、私は明らかにそのスイートを迅速に変更して json-deserializer
を調べます。 残念ながら、これは もう 1 つの危険が報告されるという結果になりました. 今朝のこれらの経験に直面して、私は自分のクレートを追求することを保護することは明らかです.紹介中JSON の解析を好む: JustJson
Rust で十分に調査されていないと判断するよりも、私は多様な信念を追求しています。 JSON クレートが存在する可能性があります)。 私はそれがいくつかのメリットがあると判断し、それが私がこの信念に少しでも関わっていた理由です. 典型的な前提は、可能な限り少ない割り当てで価値のある JSON を解析しようとしているということです。 明らかに、オブジェクトと配列は頻繁に割り当てを必要とします。記事のキーと値のペアまたは配列値のためのストレージが必要です。 文字列と浮動小数点数を遅延デコードできるときはいつでも? あなたは自分自身にさえ尋ねているでしょう。日?" 短いacknowledge:エスケープ。 JSON 文字列の表示を取り消します: "n"
。 これを Rust 文字列に大幅に変更するには、エスケープされた n
パーソナリティを表す 2 バイトを ASCII/UTF-8 表現に変換する必要があります。 私が発見したことから、JSON DOM を解析する現在のすべての Rust クレートは、解析時にエスケープをデコードします。 これは、シャッフル シーケンスに遭遇したときはいつでも、デコードされたバージョンを格納するために最新の文字列を配布する必要があることを意味します. 私の信念は、保護することですその余分な割り当てから遠く離れています。JustJsonで、Cost
フォームにはジェネリック パラメータがあります。 JSON を解析すると、返される形式は Cost
. JsonString
と JsonNumber
は解析操作中に収集された一部のメタデータとは別に、長年にわたって確立された供給への参照。 これにより、JsonString
圧力をかける PartialCmp<&str>
そのような:- エスケープが表示されない場合、基になる
&str
はストレートでもかまいませんwhen put next in Rust strings に対してビルドされた when put next implementation の使い方 - エスケープが表示されている場合は、デコードされた長さを
&str
の長さに対してチェックして保護することもできます文字列ファイルの比較から遠く離れています. - エスケープが表示されている場合、それらは文字列 c の一部として soar でデコードされます比較操作.
特にお願いしたいのは、加工助剤やダメージの延長ですか? 多くの問題と同様に、ユースケースに依存していると思います. 暫定的なベンチマーク結果 この部分の序文として、そのベンチマーク JSON を発表します。解析は神経をすり減らすシナリオです。 JSON ペイロードは大きく変動します。 納品時に、コンパクトで適切に印刷されたすべての種類の非常に洗練された、非常に複雑な JSON ペイロードとは対照的に、私は自分のライブラリを最大限に調べました: 私はこのベンチャーに約 1 日を費やしたことを考えると、これらの結果に非常に満足しています。 とはいえ、それはどうでしょうか json-benchmark
? json-deserializer
ごとに追加しました と JustJson が争いに加わり、それが DOM ベンチマークの生の出力です:
DOM========justjson========parse|stringify=files/canada.json 370 MB/秒 2010 MB/秒 ファイル/ citm_catalog.json 670 MB/s 1530 MB/s files/twitter.json 530 MB/s 3270 MB/s===json-deserializer====parse|stringify=files/canada.json 490 MB/s files/citm_catalog .json 550 MB/秒 ファイル/twitter.json 300 MB/秒=======serde_json=======parse|stringify=ファイル/canada.json 330 MB/秒 520 MB/秒 ファイル/citm_catalog .json 560 MB/s 800 MB/s files/twitter.json 410 MB/s 1110 MB/s====rustc_serialize=====parse|stringify=files/canada.json 190 MB/s 87 MB/sファイル/citm_catalog.json 300 MB/秒 230 MB/秒 ファイル/twitter.json 160 MB/秒 350 MB/秒=======simd-json========parse|stringify=files/canada.json 450 MB/s 560 MB/s files/citm_catalog.json 1380 MB/s 1060 MB/s files/twitter. json 1260MB/s 1560MB/s
これらのベンチマークは、より大きなペイロードを使用します。 canada.json には、配列の配列として保存された GPS 座標が合理的に含まれています。 citm_catalog.json は、ファイルの種類を適切に組み合わせて、適切に作成された目標ファイルの状況を備えています。 そして遅かれ早かれ、twitter.json には、理想的な量の文字列ファイルが含まれています。
私の印象的な結果stringify については、JustJson がこのベンチマークで本当にごまかしていることを考慮してください。JSON の文字列と数値が、Cost
を JSON に変換して、長い間確立された形式のままになっているという理論的根拠のために事実上一連の memcpy
です。 simd-json
は本当に印象的。 また、target_cpu=native
を使用してバイナリをコンパイルするのに十分なお金をプライベートにすることもできます。 私の特定の ActivityPub の信念では、私がそれを出荷した場合、その目的は、他のユーザーがビルド済みのバイナリをダウンロードできるようにすることである可能性があります。つまり、target_cpu=native
バイナリ互換性を最大化します。 simd-json
は target_cpu=native
なしでどのように開発されますか? ここに同じベンチマークがありますが、SIMD が有効にされていないにもかかわらず、
=======simd-json========parse|stringify=====parse|stringify====files/canada.json 310 MB/秒 560 MB/ s ファイル/citm_catalog.json 890 MB/秒 1060 MB/秒 ファイル/twitter.json 760 MB/秒 1390 MB/秒
賢く、それは私が予想するよりも早く一度に変わります! 私は canada.json
をより早く解析するコマンドを実行していますが、反対の recordsdata は simd-json を確実な勝者として提示します。一もっと信じてください
また、あなたが理解できないのは、私が幸いなことにブログを書いている瞬間を目撃したということです。私が教えられたことは、一度真実になります。 そして、その仮定を調べてみると、結果は予想よりも完全に多様化していました。 クラッチを握ると何が起こるか知っていますか?simd-json
ベンチャー。 それはかなりよく維持されているように見えますが、 健全性に関連する危険を開始する , 私は、この種の点が時間の経過とともに最も確実に対処されることを期待しています. さまざまな危険スレッドといくつかのプル リクエストをブラウジングしているときに、「テープ」構造を使用する方法について言及しているのを発見しました。 これにより、可能な限り少ない割り当てで最も怠惰な JSON パーサーに圧力をかける手法に関するもう 1 つの信念を私に導きました: ツリー全体を単一の Vec
とそれにインデックスを付けます。 そして、この日私 実装しました.
積み上げはどうですか? ここにjson-benchmark
の出力があります: 図書館canada.json citm_catalog.json twitter.json
JustJsonのパターンを継続している理由 ほぼすべてのJSONについて使用条件を解析するには、 serde-json の使用を強くお勧めします。
。 それは安定していて正当であり、Serde の快適さを打ち負かすのは困難です。 さらに、Cost
形式に解析しなくなったときに、文字列ファイルを借用する可能性が非常に高くなります。 serde-json
. 以上の何かを心に留めておく目的は、おそらくほとんどないか、まったくないでしょう。 simd-json クレートがいかに便利であるかを考えると、借用した JSON DOM パーサーを明らかにするか、Serde で受け入れ可能なより早い JSON パーサーを支持することで、安全でないコードについて合理的に依存関係を持つことを気にしなくなった私たちには、一般的にそれをお勧めします. 私は個人的に、安全でないコードは可能な限り最小限に抑える必要があると考えています。 JustJson は unsafe を使用しますが、1 つの目的には当てはまります。既に検証済みのファイルに対する 2 番目の UTF-8 検証パスをスキップすることです。これは serde-json
であり、他のファイルの広がりも達成されます。 . 現在、JustJson には unsafe ブロックにラップされた式が 3 つあります。 このクレートで徹底的に試してみました。 私が達成しようとしている特定の最後のプロセスはファザーで決定されますが、ファジングがもはやポイントを明らかにすることはないと思います.
最後に、非常に怠惰な JSON パーサーの前提は注目を集めるものであり、このレベルまで探索するのは楽しいものでした。 私のシナリオを念頭に置いて書いたので、手袋のように私のユースケースに適合します. これらすべての原因に対して
JustJsonの進行パターン 一方、ほとんどの Rust 開発者には他のライブラリを強く推奨しています 𝚆𝚊𝚝𝚌𝚑 𝙽𝙾𝚆 📺
) を使用します。 簡単な ActivityPub の演習では、次のように記述できます: { "@環境": "https://www.w3.org/ns/activitystreams"、 "形": "切手"、 "に": 、 "に起因する ": "https ://social.instance/alyssa/", "言いたいこと
": "司令官、私はその本を読むことができましたか" }
@context
) 領域は非常に重要です。ドキュメントの快適さがどのように解釈されるかを制御します。 達成すべき明確な問題の 1 つは、ドキュメントのスキーマを拡張することです: { "@環境": { "@vocab": "https://www.w3.org/ns/ activitystreams", "ext": "https://dogs-extension.instance/phrases/
", "@言語": "en
" }、 "まとめ": "ショー"、 "形": "切手", "材料を言う": "私の犬にはノミがいます.
」、「内線:鼻孔": 0、"ext:scent": "不快" }
何区ごとに非公開にネーム システムでは、@context
を参照する必要があります。 この状況では、ext:nostril
は実際には ext で定義された nostril
です。 https://dogs-extension.instance/phrases/
にある語彙。 それにもかかわらず、 ext
の使用法は完全に恣意的です。 私が意識している限りでは、Serde からの構文解析におけるこの柔軟性に対処する有能な機能として、このようなものはもはや存在しないでしょう。 現在、ActivityPub/JSON-LD 関連のクレートがいくつかありますが、特定の原因には立ち入らずに、自分の開発した実装を突き刺す必要がありました。 経験上、serde_json::Cost
は借用したファイルを保存できないことを知っていました。 私のユースケースでは、すべての文字列に約 1 分の割り当てを合理的に望むよりも、一度解析した JSON からファイルを借りることができるクレートを回収する必要がありました。 JSONのすべてのオブジェクトキーは文字列なので、それらは急速に加算されます.クレートを見つけるのは面倒です
私は、自分のニーズに合ったクレートを求めて、すべての lib.rs と crates.io を試すのに時間を費やしました。 ロード の JSON パーサーが取得可能です。 そして、それらの主な好みは、入力からファイルを借用することもできなくなります. JSON があまり洗練されていないことはわかっていたので、beget を実際に作成することは明らかでした。 Reddit にスレッドがポップアップ表示され、多くの貴重なリソースを発見しました:
)Serdeのjson-benchmark
、次にクレートを置くと:serde-json
json
simd-json
rustc-serialize
(非推奨/アーカイブ済み) json-deserializerへのアドバイス
simd-json
json
これらの最新のリソースを使用して、私は感じましたbeget の実装で時間を無駄にしてしまったのはばかげています。 私は夜の快適さのためにリラックスし、json
朝のクレート.Rust JSON エコシステムではすべてが OK ではなくなります json
クレート 、もう少し注意する必要がありました。 2020 年 3 月 18 日に最後の自由化が行われます。JSON は非常に小さな構造であるため、これは必ずしも本質的に心配する必要はありません。 それは JSONクレートが達成するために実行可能です安定性が向上し、追加の変更は不要になりました。 たとえそれが一度でも起こったとしても、過去 3 年間で 1.0 をある程度解放しないのはなぜですか? さらに、crates.io リストに README がないのはなぜですか? Github ポイントで両方のリクエストをリクエストした個人がいるかどうかは明らかです。 代わりに、私は ユーザーがベンチャーが一度見捨てられたものになるかどうかを尋ねているのを見ました。 さらに、一度報告された未定義の動作の危険性のように見えるものを見ました 2021 年 2 月 1 日 に、コメントまたは対処されていないシステムによって一度になります。 Miri でエラーを引き起こすコードがよそよそしいことを確認しました。この特定のクレートについてフレーズが展開されたかったように感じました。 ほぼ毎日ダウンロードされます。 セキュリティ勧告を提出しました) (完全に破損した監査に申し訳ありません!) および という危険性json-benchmark ベンチャー。 それで json-deserializer
、もう 1 人のコメンターが一度提案する合理的に支持された解説で? 自分のbegetライブラリを試してみてから )json.org JSON チェッカーのスイート、私は明らかにそのスイートを迅速に変更して json-deserializer
を調べます。 残念ながら、これは もう 1 つの危険が報告されるという結果になりました. 今朝のこれらの経験に直面して、私は自分のクレートを追求することを保護することは明らかです.紹介中JSON の解析を好む: JustJson
Rust で十分に調査されていないと判断するよりも、私は多様な信念を追求しています。 JSON クレートが存在する可能性があります)。 私はそれがいくつかのメリットがあると判断し、それが私がこの信念に少しでも関わっていた理由です. 典型的な前提は、可能な限り少ない割り当てで価値のある JSON を解析しようとしているということです。 明らかに、オブジェクトと配列は頻繁に割り当てを必要とします。記事のキーと値のペアまたは配列値のためのストレージが必要です。 文字列と浮動小数点数を遅延デコードできるときはいつでも? あなたは自分自身にさえ尋ねているでしょう。日?" 短いacknowledge:エスケープ。 JSON 文字列の表示を取り消します: "n"
。 これを Rust 文字列に大幅に変更するには、エスケープされた n
パーソナリティを表す 2 バイトを ASCII/UTF-8 表現に変換する必要があります。 私が発見したことから、JSON DOM を解析する現在のすべての Rust クレートは、解析時にエスケープをデコードします。 これは、シャッフル シーケンスに遭遇したときはいつでも、デコードされたバージョンを格納するために最新の文字列を配布する必要があることを意味します. 私の信念は、保護することですその余分な割り当てから遠く離れています。JustJsonで、Cost
フォームにはジェネリック パラメータがあります。 JSON を解析すると、返される形式は Cost
. JsonString
と JsonNumber
は解析操作中に収集された一部のメタデータとは別に、長年にわたって確立された供給への参照。 これにより、JsonString
圧力をかける PartialCmp<&str>
そのような:- エスケープが表示されない場合、基になる
&str
はストレートでもかまいませんwhen put next in Rust strings に対してビルドされた when put next implementation の使い方 - エスケープが表示されている場合は、デコードされた長さを
&str
の長さに対してチェックして保護することもできます文字列ファイルの比較から遠く離れています. - エスケープが表示されている場合、それらは文字列 c の一部として soar でデコードされます比較操作.
特にお願いしたいのは、加工助剤やダメージの延長ですか? 多くの問題と同様に、ユースケースに依存していると思います. 暫定的なベンチマーク結果 この部分の序文として、そのベンチマーク JSON を発表します。解析は神経をすり減らすシナリオです。 JSON ペイロードは大きく変動します。 納品時に、コンパクトで適切に印刷されたすべての種類の非常に洗練された、非常に複雑な JSON ペイロードとは対照的に、私は自分のライブラリを最大限に調べました: 私はこのベンチャーに約 1 日を費やしたことを考えると、これらの結果に非常に満足しています。 とはいえ、それはどうでしょうか json-benchmark
? json-deserializer
ごとに追加しました と JustJson が争いに加わり、それが DOM ベンチマークの生の出力です:
DOM========justjson========parse|stringify=files/canada.json 370 MB/秒 2010 MB/秒 ファイル/ citm_catalog.json 670 MB/s 1530 MB/s files/twitter.json 530 MB/s 3270 MB/s===json-deserializer====parse|stringify=files/canada.json 490 MB/s files/citm_catalog .json 550 MB/秒 ファイル/twitter.json 300 MB/秒=======serde_json=======parse|stringify=ファイル/canada.json 330 MB/秒 520 MB/秒 ファイル/citm_catalog .json 560 MB/s 800 MB/s files/twitter.json 410 MB/s 1110 MB/s====rustc_serialize=====parse|stringify=files/canada.json 190 MB/s 87 MB/sファイル/citm_catalog.json 300 MB/秒 230 MB/秒 ファイル/twitter.json 160 MB/秒 350 MB/秒=======simd-json========parse|stringify=files/canada.json 450 MB/s 560 MB/s files/citm_catalog.json 1380 MB/s 1060 MB/s files/twitter. json 1260MB/s 1560MB/s
これらのベンチマークは、より大きなペイロードを使用します。 canada.json には、配列の配列として保存された GPS 座標が合理的に含まれています。 citm_catalog.json は、ファイルの種類を適切に組み合わせて、適切に作成された目標ファイルの状況を備えています。 そして遅かれ早かれ、twitter.json には、理想的な量の文字列ファイルが含まれています。
私の印象的な結果stringify については、JustJson がこのベンチマークで本当にごまかしていることを考慮してください。JSON の文字列と数値が、Cost
を JSON に変換して、長い間確立された形式のままになっているという理論的根拠のために事実上一連の memcpy
です。 simd-json
は本当に印象的。 また、target_cpu=native
を使用してバイナリをコンパイルするのに十分なお金をプライベートにすることもできます。 私の特定の ActivityPub の信念では、私がそれを出荷した場合、その目的は、他のユーザーがビルド済みのバイナリをダウンロードできるようにすることである可能性があります。つまり、target_cpu=native
バイナリ互換性を最大化します。 simd-json
は target_cpu=native
なしでどのように開発されますか? ここに同じベンチマークがありますが、SIMD が有効にされていないにもかかわらず、
=======simd-json========parse|stringify=====parse|stringify====files/canada.json 310 MB/秒 560 MB/ s ファイル/citm_catalog.json 890 MB/秒 1060 MB/秒 ファイル/twitter.json 760 MB/秒 1390 MB/秒
賢く、それは私が予想するよりも早く一度に変わります! 私は canada.json
をより早く解析するコマンドを実行していますが、反対の recordsdata は simd-json を確実な勝者として提示します。一もっと信じてください
また、あなたが理解できないのは、私が幸いなことにブログを書いている瞬間を目撃したということです。私が教えられたことは、一度真実になります。 そして、その仮定を調べてみると、結果は予想よりも完全に多様化していました。 クラッチを握ると何が起こるか知っていますか?simd-json
ベンチャー。 それはかなりよく維持されているように見えますが、 健全性に関連する危険を開始する , 私は、この種の点が時間の経過とともに最も確実に対処されることを期待しています. さまざまな危険スレッドといくつかのプル リクエストをブラウジングしているときに、「テープ」構造を使用する方法について言及しているのを発見しました。 これにより、可能な限り少ない割り当てで最も怠惰な JSON パーサーに圧力をかける手法に関するもう 1 つの信念を私に導きました: ツリー全体を単一の Vec
とそれにインデックスを付けます。 そして、この日私 実装しました.
積み上げはどうですか? ここにjson-benchmark
の出力があります: 図書館canada.json citm_catalog.json twitter.json
JustJsonのパターンを継続している理由 ほぼすべてのJSONについて使用条件を解析するには、 serde-json の使用を強くお勧めします。
。 それは安定していて正当であり、Serde の快適さを打ち負かすのは困難です。 さらに、Cost
形式に解析しなくなったときに、文字列ファイルを借用する可能性が非常に高くなります。 serde-json
. 以上の何かを心に留めておく目的は、おそらくほとんどないか、まったくないでしょう。 simd-json クレートがいかに便利であるかを考えると、借用した JSON DOM パーサーを明らかにするか、Serde で受け入れ可能なより早い JSON パーサーを支持することで、安全でないコードについて合理的に依存関係を持つことを気にしなくなった私たちには、一般的にそれをお勧めします. 私は個人的に、安全でないコードは可能な限り最小限に抑える必要があると考えています。 JustJson は unsafe を使用しますが、1 つの目的には当てはまります。既に検証済みのファイルに対する 2 番目の UTF-8 検証パスをスキップすることです。これは serde-json
であり、他のファイルの広がりも達成されます。 . 現在、JustJson には unsafe ブロックにラップされた式が 3 つあります。 このクレートで徹底的に試してみました。 私が達成しようとしている特定の最後のプロセスはファザーで決定されますが、ファジングがもはやポイントを明らかにすることはないと思います.
最後に、非常に怠惰な JSON パーサーの前提は注目を集めるものであり、このレベルまで探索するのは楽しいものでした。 私のシナリオを念頭に置いて書いたので、手袋のように私のユースケースに適合します. これらすべての原因に対して
JustJsonの進行パターン 一方、ほとんどの Rust 開発者には他のライブラリを強く推奨しています 𝚆𝚊𝚝𝚌𝚑 𝙽𝙾𝚆 📺