Member-only story
Java, Go, Rustの比較(前半)
Java、Go、Rust を比較した記事です。長いので前半と後半に分けます。今回はアーティファクトのサイズやメモリ使用量についてみてきます。

Java、Go、Rust を比較した記事です。ベンチマークというよりも、出力された実行ファイルのサイズ、メモリ使用量、CPU使用量、ランタイム要件などを比較しました。またもちろん、第二の数字あたりのいくつかの要求を取得し、数字のいくつかの意味をしようとするための小さなベンチマークについても比較しています。
同じようなツール(たぶん?)を比較するにおいて、この比較の中でそれぞれの言語でウェブサービスを書いてみました。ウェブサービスは非常にシンプルで、3つのRESTエンドポイントにサービスを提供しています。

3つのウェブサービスのリポジトリはgithubでホストされています。
Artifact Size
バイナリがどのように構築されたかについて、お話します。Javaの場合は、maven-shade-plugin を使ってすべてを一つの大きなjarにビルドし、mvn packagetargetを使いました。Goの場合は、 go buildを使いました。最後に、Rustの場合は cargo build — releaseを使いました。

アーティファクトのコンパイルサイズは、選択したライブラリ/ディペンデンシーにもよるので、それらが肥大化している場合、コンパイルされたプログラムは同じになってしまいます。私の特定のケースでは、私が選択したライブラリの場合、上記がプログラムのコンパイルサイズです。
別のセクションでは、3つのプログラムをすべてdockerイメージとしてビルドしてパッケージ化し、それぞれの言語で必要とされるランタイムオーバーヘッドを示すために、それらのサイズもリストアップします。詳細は以下の通りです。
Memory Usage
Idle, doing nothing

何だって?アイドル実行中のメモリーフットプリントを示すGoとRustのバージョンのバーはどこにあるのでしょうか?まあ、バーはそこにありますが、JVMがプログラムを起動してアイドル状態で何もしていないときにJavaが160MBを消費するだけです。Go の場合、プログラムは 0.86 MB を使用し、Rust の場合は 0.36 MB を使用します。これは大きな違いです。ここでは、JavaはGoやRustの場合よりも2桁以上のメモリを使用しており、ただメモリの中にあるだけで何もしていません。これはリソースの大きな浪費です。
Serving REST Requests
wrkを使ってAPIにリクエストを送り、メモリとCPUの使用量と、3つのバージョンのプログラムの各エンドポイントについて、私のマシン上で達成された1秒あたりのリクエスト数を観察してみましょう。
wrk -t2 -c400 -d30s http://127.0.0.1:8080/hellowrk -t2 -c400 -d30s http://127.0.0.1:8080/greeting/Janewrk -t2 -c400 -d30s http://127.0.0.1:8080/fibonacci/35
上記の wrk コマンドには以下のように書かれています。(wrk には)2 つのスレッドを使用し、プールに 400 個のオープン接続を保持し、30 秒間 GET エンドポイントを繰り返し呼び出します。ここでは、wrk…