Aleksandr Filichkin
-5分鐘閱讀
讓我們比較一下所有支援的執行時+2個自定義執行時(Rust和GraalVM)的效能。
將比較冷啟動和熱啟動。
原始碼在這裡:https://github。com/Aleksandr-Filichkin/aws-lambda-runtimes-performance。它需要最小的本地設定(幾乎所有的都是Docker化的)。
NodeJs (14。x)
Python (3。9)
Go(1。x)
Ruby(2。7)
。Net(3。1)
Java (11)
Rust(1。54。0)
GraalVM(21。2)
免責宣告。
所有的基準都是在2021年9月進行的
我不是所有這些語言的專家,我很高興看到GitHub repo中的MR有效能改進。我將支援這些 repo,並每三個月進行一次效能測試。我相信開放原始碼的合作 :)
測試場景
我們將測試API-Gateway->AWS Lambda->DynamoDb流程。
我們將只測試POST端點,它將把資料儲存到已知的AWS區域(us-east-2)的DynamoDb表中。
主要流程
冷啟動測試
我盡了一切努力來減少冷啟動。
刪除了無用的依賴性。
儘可能多地移到初始化階段(例如,在Java中把所有東西移到靜態),以便在啟動時使用CPU的爆發。
指定了區域。
擺脫了任何DI框架
結果。
冷啟動結果
冷啟動結果
所有語言(除了Java和.Net)都有一個相當小的冷啟動。
Java甚至不能用128Mb啟動。它需要更多的記憶體。但GraalVM在這種情況下可以提供幫助。請隨意閱讀關於GraalVM和AWS Lambda的詳細頁面
在所有的設定中,Rust擊敗了所有的其它語言,唯一的例外是128MB的Python是最好的。
龐大的設定只對Java和。Net有幫助。
熱啟動測試
測試是向每個lambda逐一發送15,000個請求。
對於負載測試,我使用JMeter。它看起來像。
我們將檢查哪些指標?
每種語言的平均(每分鐘)持續時間(256MB設定,(128MB的簡短結果你可以在最後找到)。
每種語言的最長(每分鐘)時間(256MB設定)。
NodeJS
NodeJS有一個預期的行為。
開始的時候很慢,但經過JIT最佳化後會變得更好。
NodeJS 256MB的平均持續時間
NodeJS 256MB的最大持續時間
Python
具有穩定的效能:第100次和第15000次呼叫是一樣的。
Python 256MB的平均持續時間
Python 最大持續時間為256MB
Ruby
我觀察到Ruby非常奇怪的行為:平均持續時間在增長(看起來像是記憶體洩漏或程式碼中的錯誤)。
紅寶石256MB的平均時間
紅寶石 256MB 最大持續時間
。NET
最初的~1千次呼叫很慢,但隨後它的效能非常好。
。Net 256MB的平均持續時間
。Net的最大持續時間為256MB
Golang
穩定的彈性效能。
Golang 256MB的平均持續時間
Golang 256MB的最大持續時間
Java
最初的~1千次迭代很慢,然後變得更快(JIT C1有幫助)。
Java 256MB的平均時間
Java最大持續時間為256MB
對於Java,我期望C2 JIT最佳化在1萬次迭代後進行,但即使在2萬次呼叫後也沒有最佳化,而且持續時間是一樣的。請看下面的螢幕。
Java 256 MB,沒有C2最佳化。
GraalVM
正如預期的那樣,GraalVM從一開始就具有穩定的良好效能。
GraalVM 256MB的平均時間
GraalVM 256MB的最大持續時間
Rust
Rust有一個持續的令人敬畏的表現。
Rust 256MB的平均持續時間
Rust 256MB的最大持續時間
全部在一起
衡量平均效能是非常棘手的,因為每一個新的lambda都有一些不同的結果(我相信這是因為lambdas在不同的硬體上分配)。我運行了3次測試,兩次測試之間有30分鐘的延遲,以便有3個不同的lambdas分配。
3個時間段的5K迭代(256MB Lambda)。
256 MB Lambda
此外,我還測試了128MB lambda的相同流量。在這裡我們可以看到一個很大的區別。
128MB的平均溫度狀態
128MB的平均溫度狀態
最大128MB(每分鐘)溫熱狀態
我想對於CPU密集型的流程來說,
編譯語言
和
解釋語言
之間的差異
會更大。我想,GraalVM在128MB的情況下表現不佳,因為它裡面還有JVM,它需要太多的記憶體,而且Lambda經常執行GC。
結論
冷啟動
所有語言(除了Java和.Net)都有一個相當小的冷啟動。
Java甚至不能用128Mb啟動。它需要更多的記憶體。但GraalVM在這種情況下可以提供幫助。
在所有的設定中,Rust在冷啟動時都勝過所有的執行時間,唯一的例外是128MB,Python是最好的。
熱啟動
Golang和Rust是贏家。他們有同樣出色的表現。
。Net的效能幾乎與Golang和Rust相同,但只是在1千次迭代後(JIT後)。
GraalVM有一個穩定的偉大的效能,幾乎與。Net相同,比Rust和Golang差一點。但對於最小的設定來說, 它的效能並不理想。
與。Net一樣,Java也需要一些時間(1-3千次迭代)進行JIT(C1)。不幸的是,在這個特定的用例中,我無法在JIT C2編譯後達到預期的良好效能。也許AWS只是禁用了它。
Python具有穩定的良好效能,但對於128MB的計算機來說工作速度太慢。
Ruby的效能幾乎與Python相同,但我們看到在20分鐘的呼叫後(15000次迭代後),一些持續時間在增長。
NodeJs是最慢的執行時間,經過一段時間後,它變得更好了(JIT),但仍然不夠好。此外,我們看到NodeJS的最大持續時間最差。
冷+暖啟動
的贏家是Golang和Rust
。它們總是比其他執行時更快,並表現出非常穩定的結果。