Go 還是 TinyGo?

什麼是 TinyGo?TinyGo 與 Go 有何不同? TinyGo 與 Go 相比性能如何?

什麼是 TinyGo?

TinyGo 不是另一種編程語言。它只是 Go 語言的一個編譯器。關鍵區別在於 TinyGo 編譯器創建的二進制文件更小, 主要用於嵌入式系統和 WASM。而 Go 編譯器則用於編譯完整的服務器端應用程序和通用程序。

TinyGo 使用 LLVM 作爲後端, 與 Go 編譯器相比可以創建更小的二進制文件。例如, 一個簡單的打印 "Hello World" 的代碼用 Go 編譯可能會產生約 800 KB 的二進制文件大小, 而 TinyGo 在去除不必要的符號後可以將其減少到約 10 KB。

TinyGo 專門用於資源有限的環境, 允許開發人員在各種微控制器和小型設備 (如 Arduino 和 Raspberry Pi) 上運行 Go 代碼, 這些設備通常不受標準 Go 編譯器支持。

TinyGo 的特性和限制

  1. Cgo

雖然 TinyGo 嵌入了 Clang[1] 編譯器來解析 import"C" 塊, 但 Cgo 的一些功能仍不受支持或可能工作方式略有不同。例如, #cgo 語句只得到部分支持。

  1. 反射

許多包, 特別是標準庫中的包, 依賴反射來工作。reflect 包在 TinyGo 中已經重新實現, 大部分功能都可以使用, 但有些部分尚未完全支持。

  1. 映射

映射通常工作正常, 但可能比你預期的要慢。這有幾個原因, 其中之一是某些類型 (如結構體) 可能在內部使用反射進行比較, 而不是使用專用的哈希 / 比較函數。

  1. 標準庫

由於上述缺失的部分, 以及因爲標準庫的部分依賴於所使用的特定編譯器 / 運行時, 許多包尚未編譯。請參閱 這裏的可編譯包列表 [2] (但請注意,"可編譯" 並不意味着完全可用)。

  1. 垃圾回收

垃圾回收通常工作正常, 但在非常小的芯片 (AVR) 和 WebAssembly 上可能效果不佳。它也比通常的 Go 垃圾回收器慢得多。仔細的設計可以避免在主循環中進行內存分配, 這可能會大大降低性能。你可以使用 -print-allocs=. 選項編譯, 以瞭解內存分配發生的位置和原因。有關更多信息, 請參閱 堆分配 [3] 。

要了解更多關於語言支持的信息, 請查看 這裏 [4] 。

  1. 全局變量

TinyGo 在編譯期間計算全局變量, 這可以優化啓動時間並減少內存使用, 而 Go 編譯器則以不同方式處理全局變量。這是一個重要的優化, 原因如下:

附加內容

我比較了使用 Go 和 TinyGo 編譯的 WASM 與 JavaScript 的性能, 結果令人驚訝。在發現 TinyGo 之前, 我對 Go WASM 並不太滿意。我將在下一篇博客中分享完整的教程和我的發現。

結論

總而言之,TinyGo 通過使 Go 能夠在受限環境中運行,擴展了 Go 的能力,同時犧牲了標準 Go 編譯器中的一些功能和性能優化。它對於針對物聯網設備和 WebAssembly 應用程序的開發人員特別有用,因爲在這些場景中,二進制文件大小和資源效率至關重要。

參考鏈接

  1. Clang: https://clang.llvm.org/

  2. 這裏的可編譯包列表: https://tinygo.org/docs/reference/lang-support/stdlib/

  3. 堆分配: https://tinygo.org/docs/concepts/compiler-internals/heap-allocation/

  4. 這裏: https://tinygo.org/docs/reference/lang-support/

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/wBlBbhNjYvim3wVrQfYOtg