Wasm 組件模型和慣用的程式碼生成
Arcjet 將 WebAssembly 與我們的安全即程式碼 SDK 捆綁在一起。這有助於開發人員直接在程式碼中實現常見的安全功能,例如 PII 檢測和機器人檢測。大部分邏輯都嵌入到 Wasm 中,它為我們提供了一個具有接近本機性能的安全沙箱,並且是我們關於本地優先安全的理念的一部分。
跨平台運行相同程式碼的能力也很有幫助,因為我們建立了從JavaScript 到其他技術堆疊的支持,但它需要一個重要的抽象來在語言之間進行翻譯(我們的Wasm 是從Rust 編譯的)。
WebAssembly 元件模型 是實現這一點的強大構造,但構造只能與它周圍的實現和工具一樣好。對於元件模型,這在主機(執行 WebAssembly 元件模型的環境)和來賓(以任何語言編寫並編譯到元件模型的 WebAssembly 模組;在我們的例子中為 Rust)的程式碼產生中最為明顯。
元件模型定義了主機和來賓之間通訊的語言,主要由類型、函數、匯入和匯出組成。它試圖定義一種廣泛的語言,但某些類型,例如變體、元組和資源,可能不存在於給定的通用程式語言中。
當工具嘗試為其中一種語言產生程式碼時,作者通常需要發揮創意,將元件模型類型對應到該通用語言。例如,我們使用 jco 來產生 JS 綁定,並使用 { tag: string, value: string } 形式的 JavaScript 物件實作變體。它甚至有結果<_ _> 的特殊情況。類型,其中錯誤變體將轉換為錯誤並拋出。
這篇文章探討了 Wasm 元件模型如何實現跨語言整合、主機和來賓程式碼產生的複雜性,以及我們為用 Go 等語言實現慣用程式碼所做的權衡。
Go 的主機程式碼生成
在 Arcjet,我們必須建立一個工具來為用 Go 程式語言編寫的主機產生程式碼。儘管我們的 SDK 嘗試在本地分析所有內容,但這並不總是可行,因此我們有用 Go 編寫的 API,它透過附加元資料增強本地決策。
Go 在設計上有一個非常小的語法和類型系統。他們直到最近才推出仿製藥,而且仍然有很大的限制。這使得從組件模型到 Go 的程式碼生成在各個方面都變得複雜。
例如,我們可以產生結果<_ _>;如:
但是,這限制了錯誤位置可以提供的類型。所以我們需要將其編碼為:
這可以工作,但與其他慣用的 Go 一起使用會變得很麻煩,後者通常使用 val, err := doSomething() 約定來指示與我們上面定義的 Result 類型相同的語義。
此外,建構這個 Result 很麻煩:Result[int, string]{value: 1, err: ""}。我們可能希望匹配慣用模式,而不是提供 Result 類型,以便 Go 用戶能夠自然地使用我們產生的綁定。
慣用映射與直接映射
可以產生使語言感覺更自然的程式碼,也可以更直接地對應到元件模型類型。這兩個選項都不適合 100% 的用例,因此由工具作者決定哪個最有意義。
對於 Arcjet 工具,我們為選項選擇了慣用的 Go 方法<_>;結果<_>類型,分別映射到 val, ok := doSomething() 和 val, err := doSomething()。對於變體,我們建立每個變體需要實現的接口,例如:
這在類型安全和不必要的包裝之間取得了良好的平衡。當然,也有需要包裹的情況,但這些可以作為邊緣情況處理。
開發人員可能會遇到非慣用的模式,導致程式碼冗長且難以維護。使用既定約定使程式碼感覺更熟悉,但確實需要一些額外的努力來實現。
我們決定採取慣用的方式來最大程度地減少摩擦,讓我們的團隊更輕鬆,這樣我們就知道在程式碼庫中移動時會發生什麼。
呼叫約定
工具作者需要做出的最大決定之一是綁定的呼叫約定。這包括決定如何/何時編譯導入、是否在設定或實例化期間編譯 Wasm 模組以及清理。
在Arcjet程式碼庫中,我們選擇工廠/實例模式來最佳化效能。編譯 WebAssembly 模組的成本很高,因此我們在 NewBotFactory() 建構函式中執行一次。隨後的 Instantiate() 呼叫既快速又便宜,從而在生產工作負載中實現高吞吐量。
消費者透過呼叫 NewBotFactory(ctx) 來建構此 BotFactory 一次,並使用它透過 Instantiate 方法建立多個實例。
如果模組已經編譯過,實例化會非常快,就像我們在建構工廠時使用runtime.CompileModule() 所做的那樣。
BotInstance 具有從組件模型定義導出的函數。
通常,在使用 BotInstance 後,我們希望清理它以確保不會洩漏記憶體。為此,我們提供了關閉函數。
如果你想清理整個BotFactory,也可以關掉它:
我們可以將所有這些 API 放在一起來呼叫此 WebAssembly 模組上的函數:
這個工廠和實例建置模式需要使用更多程式碼,但選擇它是為了在 Arcjet 服務的熱路徑中實現盡可能多的效能。
透過預先載入編譯成本,我們確保在 Arcjet 服務的熱路徑中(延遲最重要)請求處理盡可能有效率。這種權衡確實增加了初始化程式碼的複雜性,但它的回報是每個請求的開銷大大降低 - 請參閱我們對權衡的討論。
權衡
任何時候我們需要整合兩種或多種語言,都需要做出權衡——無論是使用原生 FFI 還是組件模型。
這篇文章討論了我們在 Arcjet 遇到的一些挑戰以及我們決定背後的原因。如果我們都基於同一組原語(例如組件模型和WIT)進行構建,那麼我們都可以利用同一組高品質原語,例如wit-bindgen 或wit-component ,並建立適合每個用例的工具。這就是為什麼制定標準對每個人都有幫助。
WebAssembly 元件模型為跨語言整合提供了強大的抽象,但將其類型轉換為 Go 等語言會帶來微妙的設計挑戰。透過選擇慣用的模式並選擇性地最佳化效能(例如使用工廠/實例模式),我們可以在保持效率的同時提供自然的開發人員體驗。
隨著組件模型工具的發展,我們可以期待更精細的程式碼產生方法來進一步簡化這些整合。
以上是Wasm 組件模型和慣用的程式碼生成的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Go語言在構建高效且可擴展的系統中表現出色,其優勢包括:1.高性能:編譯成機器碼,運行速度快;2.並發編程:通過goroutines和channels簡化多任務處理;3.簡潔性:語法簡潔,降低學習和維護成本;4.跨平台:支持跨平台編譯,方便部署。

Golang在並發性上優於C ,而C 在原始速度上優於Golang。 1)Golang通過goroutine和channel實現高效並發,適合處理大量並發任務。 2)C 通過編譯器優化和標準庫,提供接近硬件的高性能,適合需要極致優化的應用。

Golang和Python各有优势:Golang适合高性能和并发编程,Python适用于数据科学和Web开发。Golang以其并发模型和高效性能著称,Python则以简洁语法和丰富库生态系统著称。

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

Golang和C 在性能競賽中的表現各有優勢:1)Golang適合高並發和快速開發,2)C 提供更高性能和細粒度控制。選擇應基於項目需求和團隊技術棧。

goimpactsdevelopmentpositationality throughspeed,效率和模擬性。 1)速度:gocompilesquicklyandrunseff,IdealforlargeProjects.2)效率:效率:ITScomprehenSevestAndardArdardArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdEcceSteral Depentencies,增強的Depleflovelmentimency.3)簡單性。

C 更適合需要直接控制硬件資源和高性能優化的場景,而Golang更適合需要快速開發和高並發處理的場景。 1.C 的優勢在於其接近硬件的特性和高度的優化能力,適合遊戲開發等高性能需求。 2.Golang的優勢在於其簡潔的語法和天然的並發支持,適合高並發服務開發。

Golang和C 在性能上的差異主要體現在內存管理、編譯優化和運行時效率等方面。 1)Golang的垃圾回收機制方便但可能影響性能,2)C 的手動內存管理和編譯器優化在遞歸計算中表現更為高效。
