以前やってたベンチマークをリベンジ。
ソース: 【GitHub】AsyncBenchmark
経緯
- 非同期処理を少し触る機会があったので、学びなおそうと思った
- 久々にいろいろなプログラミング言語を触りたいと思った
- 新しい非同期手法があるか確認したかった
処理内容
- スリープ(100~1000ms)
- たらい回し関数(12, 6, 0)
- フィボナッチ数計算(31~40)
処理方法
- 同期処理
- 非同期処理
- シングルスレッド
- マルチスレッド
- マルチプロセス
言語(処理系)
- C++(g++)
- D(dmd)
- JavaScript(Node.js)
- C#(dotnet-script)
- CommonLisp(SBCL)
- Python(CPython、PyPy)
- HSP
- R(GNU R)
環境
- Windows11(ゲーミングノート)
実施結果
考察
- C++、Dのコンパイル言語は同期・非同期処理問わずに最速となった
- JITコンパイル系※の処理系もこれに続く結果となった
※Node.js、.Net、SBCL、PyPy - インタプリタ系※の処理系は目立って遅かった
※CPython、HSP、R - JITコンパイルはコンパイルより確かに遅いが、差はかなり小さい
(型付けの適当なjsでここまで早いのは逆に異常。流石はブラウザ戦争の賜物というところ) - PyPyはやはり早い。ただ、CPythonの完全代替までは届かないのが惜しい(今でもそのままのコードで動かせないことがある)
- GNU Rの遅さがヤバい。ベクトル計算をうまく活用できれば早くできそうな気はするけど独自のチューニング技術が必要そう
- GNU RにはWindowsでマルチスレッドを使用することができないらしい。Windowsへの最適化の甘さみたいなものも遅くなる一因として考えられるのかも
- シングルスレッドによる非同期処理※ではスリープ処理以外の並行処理ができていないことが見て取れる。使いどころは加味して選択しなければならない
※JS Promise、Python ayincio - PythonのマルチスレッドではGILの影響でシングルスレッドの非同期とほぼ同じになった
GILはPyPyでも有効な様子
結論
- JITコンパイルって凄い
余談とか感想
-
ソースコードは勉強がてらに無理やりいろんな書き方をしている
-
C#のコンパイル版がない理由は以下の理由
- 軽く測ってみた結果だとあまり差が見られなかった(ただし、最適化すれば変わるかも)
- エントリポイントの変更が必要
- .Netのコンパイルはプロジェクトファイルが必要で面倒
- .Net Framework版でも別の修正が必要になるかも
-
C++については導入が手軽なg++のみにした。cl.exeは導入が面倒なので非実施(VSと抱き合わせだよね?)
-
CommonLispには仕様にスレッドが入っていないのでSBCL付属ライブラリで対応
-
Rの内部計測時間と実時間の差おかしいので60倍で補正。時間を分で得ている…?
-
コンパイル言語だとうまくやれば最適化次第で計算後の結果をあらかじめ持たせられると思う
-
JSはスレッドもマルチプロセスの書けるようになったけど、文法が異質すぎる
async/awaitだけでマルチスレッドできる方法が欲しくない? -
C++は大体ChatGPTに書いてもらった
-
D言語で凄く苦しんだ。ChatGPTとペアプログラミングしてたけど、マイナー寄りの言語だと平気で嘘吐いてくるから困る
- sendとreceiveの挙動の理解に苦しんだ
- Dのthreadの結果がうまく収集できなかったので対象外にした
- コンパイル通った後のエラー発生率が結構高くて辛い
-
HSPは結構無理やりマルチプロセスにしている。GUI版のHSPには部分的なマルチスレッドに対応しているらしい
- mistのマルチスレッドを使用するのも一つの手ではある
- データのやり時は共有メモリではなくファイルを使用。共有メモリは標準ライブラリではサポートされていないため