15 ポイント 投稿者 ttyy1234 2024-11-29 | 10件のコメント | WhatsAppで共有

Rust、C#、Python、Go、Java、NodeJS などの最新バージョンで100万個の同時タスクを処理するプログラムを実行し、メモリ効率を比較しました。

C#(NativeAOT)と Rust が最も優れたメモリ効率を示し、Go は期待より高いメモリ消費で低い評価となりました。全体として .NET と Rust の性能が際立ち、Java(GraalVM)も驚くべき改善を見せました。

具体的には、Rust は約29MBで最も少ないメモリを使用し、C# NativeAOT は約71MBでそれに続きました。NodeJS は232MB、Python は339MBを記録しました。Go は753MBと相対的に高いメモリ使用量を示し、残念な結果となりました。Java(GraalVM)は92MBと大きな改善を見せました。

10件のコメント

 
kroisse 2024-12-02

ベンチマークコードを見ると、Rust と Python の場合、実際には concurrent task を作成しているのではなく、非同期ではあるものの他の task と並列に動作することはできない future オブジェクトだけを生成しているように見えます。おそらく C# も似たケースではないかと思います。一方で Go のコードは、それ自体が call stack などを持つ task である goroutine を生成するようになっており、100 万個のケースで Go のメモリ使用量が突出して見える原因はここにあるのではないかと思います。

 
bungker 2024-11-30

Goを擁護するなら、Goは100万個動く関数の中にどんなライブラリがあっても動作します。go を付けるだけで済みます。非同期ベースの他の言語では、途中に同期方式で少し時間を食うライブラリがあると、これが非同期の利点をすべて食い潰してしまうひどい状況になってしまいます。
非同期の利点を100%享受するには、少しでも時間を食う関数はすべて非同期に変えなければなりません。
JavaのVirtualThreadは、うーん……今回うちの会社でJavaのVirtualThreadを信じて進めたものの、ライブラリ互換性の問題のせいで結局普通のスレッドに切り替え、インスタンスを数十個立てるエンディングを迎えました。

 
roxie 2024-12-01

互換性の部分について、もう少し詳しく聞かせてもらえますか? :eyes:

 
secret3056 2024-12-02

Springでよく言われる「WebFluxをきちんと使うには、JPAではなくR2DBCと一緒に使ってこそ真価が発揮される」という話は、必ずしもそうとは言えないですね。

 
bungker 2024-12-01

ms の msal ライブラリが virtual thread で動作しないという話を聞きました

 
vwjdalsgkv 2024-12-02

例として挙げていただいた msal ライブラリは、Go の場合でもスレッドセーフでないデータ型、あるいはそのような構造が使われているライブラリであれば、同様のケースになると思います。

 
riki3 2024-12-02

スレッドセーフ性と何の関係があるのでしょうか? goroutine はそもそもスレッドセーフ性を保証する仕組みではないはずですが。

 
hookim 2024-11-30

情報ありがとうございます。

質問したいことがあります。
では、go を除く他の言語は、おっしゃっていたように同期方式のライブラリがあるとすべて破綻してしまうのでしょうか?
それとも、他の言語の中にも go のように完全な非同期をサポートする言語があるのか気になります

 
riki3 2024-11-30

colorless という表現があります。非同期と同期を区別する必要がない言語は、Go が唯一です。ユーザーの立場から見て、並行性が必要なプログラミングをするとき、難易度や使いやすさの面で Go には圧倒的な強みがあります。
最適化された非同期プログラミングより性能は少し劣るかもしれませんが。

 
bungker 2024-11-30

ご指摘ありがとうございます。表現が壊れているという点と、「完全な非同期」という表現について、誤っている部分だけ申し上げます。非同期でも同期方式のライブラリを使って構いません。ただし、短時間で完了する保証がある場合に限ります。同期方式で実行時間の長い呼び出しがあると、ほかの非同期処理が遅れてしまうため問題が生じるのです。

Go は goroutine によって億単位の作業を割り当てることもできるので、言語自体に非同期という概念はありません。使う側の立場では、どんな関数でも go を付けて呼び出せば並列で実行されるので、とても便利です。

個人的には、完全な非同期は言語自体の根幹が非同期である JavaScript ではないかと思います。