Wasm コンポーネント モデルと慣用的な codegen
Arcjet には、WebAssembly と Security as Code SDK がバンドルされています。これは、開発者が PII 検出やボット検出などの一般的なセキュリティ機能をコードに直接実装するのに役立ちます。ロジックの多くは Wasm に埋め込まれており、ネイティブに近いパフォーマンスを備えた安全なサンドボックスを提供し、ローカルファースト セキュリティに関する私たちの哲学の一部です。
プラットフォーム間で同じコードを実行できる機能も、JavaScript から他の技術スタックへのサポートを構築する際に役立ちますが、言語間で変換するには重要な抽象化が必要です (Wasm は Rust からコンパイルされています)。
WebAssembly コンポーネント モデル はこれを可能にする強力な構造ですが、その構造はそれを囲む実装とツールによってのみ優れています。コンポーネント モデルの場合、これはホスト (WebAssembly コンポーネント モデルを実行する環境) とゲスト (任意の言語で記述され、コンポーネント モデルにコンパイルされた WebAssembly モジュール。この場合は Rust) のコード生成で最も明らかです。
コンポーネント モデルは、主に型、関数、インポート、エクスポートで構成されるホストとゲスト間の通信用の言語を定義します。幅広い言語を定義しようとしていますが、バリアント、タプル、リソースなどの一部の型は、特定の汎用プログラミング言語に存在しない可能性があります。
ツールがこれらの言語のいずれかのコードを生成しようとする場合、作成者は多くの場合、コンポーネント モデル タイプをその汎用言語にマッピングするために創造性を発揮する必要があります。たとえば、JS バインディングの生成には jco を使用します。これにより、{ タグ: 文字列、値: 文字列 } の形式の JavaScript オブジェクトを使用してバリアントが実装されます。結果には特殊なケースもあります<_, _>エラーのバリアントが Error に変換されてスローされるタイプ。
この投稿では、Wasm コンポーネント モデルが言語間の統合をどのように可能にするか、ホストとゲストのコード生成の複雑さ、Go などの言語で慣用的なコードを実現するために行うトレードオフについて説明します。
Go 用のホスト コード生成
Arcjet では、Go プログラミング言語で書かれたホスト用のコードを生成するツールを構築する必要がありました。私たちの SDK はすべてをローカルで分析しようとしますが、それが常に可能であるとは限らないため、Go で書かれた API を用意し、追加のメタデータでローカルの決定を強化します。
Go は設計上、非常に最小限の構文と型システムを備えています。ごく最近までジェネリック医薬品さえありませんでしたが、依然として重大な制限があります。これにより、コンポーネント モデルから Go へのコード生成がさまざまな点で複雑になります。
たとえば、次のような結果を生成できます<_, _>として:
type Result[V any] struct { value V err error }
ただし、エラー位置に提供できる型が制限されます。したがって、次のようにコード生成する必要があります:
type Result[V any] struct { value V err error }
これは機能しますが、他の慣用的な Go で使用すると面倒になります。Go では、上で定義した Result タイプと同じセマンティクスを示すために val, err := doSomething() 規則がよく使用されます。
さらに、この Result の構築は面倒です: Result[int, string]{value: 1, err: ""}。 Result タイプを提供する代わりに、Go ユーザーが生成されたバインディングを自然に利用できるように、慣用的なパターンに一致させたいと考えています。
慣用的マッピングと直接マッピング
コードは、言語にとってより自然に感じられるように生成することも、コンポーネント モデル タイプへのより直接的なマッピングにすることもできます。どちらのオプションも 100% のユースケースに適合するわけではないため、どちらが最も合理的であるかを判断するのはツールの作成者次第です。
Arcjet ツールの場合、オプションとして慣用的な Go アプローチを選択しました<_>結果<_, _>これらの型は、それぞれ val, ok := doSomething() および val, err := doSomething() にマップされます。バリアントの場合、各バリアントが実装する必要がある次のようなインターフェイスを作成します。
type Result[V any, E any] struct { value V err E }
これにより、型の安全性と不必要なラッピングのバランスが取れています。もちろん、ラッピングが必要な状況もありますが、それはエッジケースとして処理できます。
開発者は、非慣用的なパターンに苦労し、冗長で保守性の低いコードにつながる可能性があります。確立された規則を使用すると、コードがより親しみやすくなりますが、実装には追加の作業が必要になります。
コードベースを移動する際に何が起こるかを理解できるように、摩擦を最小限に抑え、チームにとって作業を容易にする慣用的な方法を採用することにしました。
呼び出し規約
ツール作成者が行う必要がある最大の決定の 1 つは、バインディングの呼び出し規約です。これには、インポートをいつどのようにコンパイルするか、Wasm モジュールをセットアップ中またはインスタンス化中、およびクリーンアップ中にコンパイルするかどうかの決定が含まれます。
Arcjet コードベースでは、パフォーマンスを最適化するためにファクトリ/インスタンス パターンを選択しました。 WebAssembly モジュールのコンパイルにはコストがかかるため、NewBotFactory() コンストラクターで 1 回だけ実行します。後続の Instantiate() 呼び出しは高速かつ安価であり、実稼働ワークロードでの高スループットが可能になります。
type BotConfig interface { isBotConfig() } func (AllowedBotConfig) isBotConfig() {} func (DeniedBotConfig) isBotConfig() {}
消費者は NewBotFactory(ctx) を呼び出してこの BotFactory を 1 回構築し、それを使用して Instantiate メソッド経由で複数のインスタンスを作成します。
func NewBotFactory( ctx context.Context, ) (*BotFactory, error) { runtime := wazero.NewRuntime(ctx) // ... Imports are compiled here if there are any // Compiling the module takes a LONG time, so we want to do it once and hold // onto it with the Runtime module, err := runtime.CompileModule(ctx, wasmFileBot) if err != nil { return nil, err } return &BotFactory{runtime, module}, nil }
ファクトリを構築するときに runtime.CompileModule() を使用するように、モジュールがすでにコンパイルされている場合、インスタンス化は非常に高速です。
BotInstance には、コンポーネント モデル定義からエクスポートされた関数があります。
func (f *BotFactory) Instantiate(ctx context.Context) (*BotInstance, error) { if module, err := f.runtime.InstantiateModule(ctx, f.module, wazero.NewModuleConfig()); err != nil { return nil, err } else { return &BotInstance{module}, nil } }
通常、BotInstance を使用した後は、メモリ リークが発生していないことを確認するために、BotInstance をクリーンアップする必要があります。このために、Close 関数を提供します。
func (i *BotInstance) Detect( ctx context.Context, request string, options BotConfig, ) (BotResult, error) { // ... Lots of generated code for binding to Wazero }
BotFactory 全体をクリーンアップしたい場合は、それを閉じることもできます:
type Result[V any] struct { value V err error }
これらの API をすべてまとめて、この WebAssembly モジュールの関数を呼び出すことができます。
type Result[V any, E any] struct { value V err E }
このファクトリーとインスタンスの構築パターンでは使用するコードが多くなりますが、Arcjet サービスのホット パスで可能な限り多くのパフォーマンスを達成するために選択されました。
コンパイル コストを前倒しすることで、Arcjet サービスのホット パス (レイテンシーが最も重要な場所) でのリクエスト処理が可能な限り効率的になるようにします。このトレードオフにより、初期化コードは多少複雑になりますが、リクエストごとのオーバーヘッドが大幅に減少するというメリットがあります。トレードオフについての説明を参照してください。
トレードオフ
2 つ以上の言語を統合する必要がある場合は常に、ネイティブ FFI を使用する かコンポーネント モデルを使用するかにかかわらず、トレードオフを行う必要があります。
この投稿では、アークジェットで遭遇したいくつかの課題と、その決定の背後にある理由について説明しました。コンポーネント モデルや WIT などの同じプリミティブのセットを全員が構築すると、wit-bindgen や wit-component などの高品質のプリミティブの同じセットを活用できます。 を使用して、あらゆるユースケースに適したツールを構築します。これが、標準に向けた取り組みがすべての人に役立つ理由です。
WebAssembly コンポーネント モデルは、言語間の統合のための強力な抽象化を提供しますが、その型を Go などの言語に変換すると、微妙な設計上の課題が生じます。ファクトリ/インスタンス パターンの使用など、慣用的なパターンを選択し、パフォーマンスを選択的に最適化することで、効率を維持しながら自然な開発者エクスペリエンスを提供できます。
コンポーネント モデルに関するツールが進化するにつれて、これらの統合をさらに簡素化する、より洗練されたコード生成アプローチが期待できます。
以上がWasm コンポーネント モデルと慣用的な codegenの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











Golangは、パフォーマンスとスケーラビリティの点でPythonよりも優れています。 1)Golangのコンピレーションタイプの特性と効率的な並行性モデルにより、高い並行性シナリオでうまく機能します。 2)Pythonは解釈された言語として、ゆっくりと実行されますが、Cythonなどのツールを介してパフォーマンスを最適化できます。

Golangは並行性がCよりも優れていますが、Cは生の速度ではGolangよりも優れています。 1)Golangは、GoroutineとChannelを通じて効率的な並行性を達成します。これは、多数の同時タスクの処理に適しています。 2)Cコンパイラの最適化と標準ライブラリを介して、極端な最適化を必要とするアプリケーションに適したハードウェアに近い高性能を提供します。

goisidealforforbeginnersandsutable forcloudnetworkservicesduetoitssimplicity、andconcurrencyfeatures.1)installgofromtheofficialwebsiteandverify with'goversion'.2)

Golangは迅速な発展と同時シナリオに適しており、Cは極端なパフォーマンスと低レベルの制御が必要なシナリオに適しています。 1)Golangは、ごみ収集と並行機関のメカニズムを通じてパフォーマンスを向上させ、高配列Webサービス開発に適しています。 2)Cは、手動のメモリ管理とコンパイラの最適化を通じて究極のパフォーマンスを実現し、埋め込みシステム開発に適しています。

speed、効率、およびシンプル性をspeedsped.1)speed:gocompilesquilesquicklyandrunseffictient、理想的なlargeprojects.2)効率:等系dribribraryreducesexexternaldedenciess、開発効果を高める3)シンプルさ:

GolangとPythonにはそれぞれ独自の利点があります。Golangは高性能と同時プログラミングに適していますが、PythonはデータサイエンスとWeb開発に適しています。 Golangは同時性モデルと効率的なパフォーマンスで知られていますが、Pythonは簡潔な構文とリッチライブラリエコシステムで知られています。

GolangとCのパフォーマンスの違いは、主にメモリ管理、コンピレーションの最適化、ランタイム効率に反映されています。 1)Golangのゴミ収集メカニズムは便利ですが、パフォーマンスに影響を与える可能性があります。

GolangとCにはそれぞれパフォーマンス競争において独自の利点があります。1)Golangは、高い並行性と迅速な発展に適しており、2)Cはより高いパフォーマンスと微細な制御を提供します。選択は、プロジェクトの要件とチームテクノロジースタックに基づいている必要があります。
