これは何?
もともと
https://qiita.com/fsdg-adachi_h/items/5feeda2ed19f879fdf9a
という URL で公開されていた記事に
というコメントを書いたら、その記事は削除されて。
同じ方が、全く同じような内容で
という記事を公開されて。
なぜか私はコメントできない(ブロックされてるのかな)ようなので、コメントで書きたかった追加情報に関する記事を書こうと思った。
int の長さの影響なのかどうか
元のコードが go は int
。環境から類推するに 64bit 整数。
C / C++ は、おそらく 32bit。Java の int は 32bit。ということで不公平。
※ 公平になりようがない Python・NodeJS なんかもいるので完全な公平は期待できない。そういう意味で、元の記事が悪いということではない。
というわけで、
// フィボナッチ数列を再帰的な方法で計算する関数
func fibonacci(n int32) int32 {
if n == 0 || n == 1 {
return n
} else {
return fibonacci(n-2) + fibonacci(n-1)
}
}
を加えてみた。
環境
環境は元記事とは全然違い、MacBook Pro (Apple M1 非Max)。
コンパイラやら VM やらは、下記。
- Apple clang version 14.0.3 (clang-1403.0.22.14.1) Target: arm64-apple-darwin22.6.0
- g++-13 (Homebrew GCC 13.1.0) 13.1.0
- gcc-13 (Homebrew GCC 13.1.0) 13.1.0
- openjdk version "20.0.2" 2023-07-18
- OpenJDK Runtime Environment (build 20.0.2+9-78)
- OpenJDK 64-Bit Server VM (build 20.0.2+9-78, mixed mode, sharing)
- go version go1.20.6
そういえば、元の記事で gcc は 11.4.0 なのに g++ は 11.3.0 なのが気になっていた。Ubuntu だとよくある環境なのかな。
Rust・Node・Python は入れなかった。なんとなく。
結果
こんな感じ。
横軸は時間なので、長いほうが遅い。
参加者の説明をすると。
名前 | 説明 |
---|---|
java | 普通に java で実行 |
goint32 | go で、int を 32bit にしたもの |
goint | go で int を使ったもの。つまり 64bit |
rosetta_c | C言語。clang で x86_64-apple-darwin でビルド。Rosetta2 で実行 |
gcc | C言語。gcc-13 でネイティブコードを作って実行 |
clang | C言語。clang でネイティブコードを作って実行 |
rosetta_cpp | C++。clang++ で x86_64-apple-darwin でビルド。Rosetta2 で実行 |
gpp | C++。g++-13 でネイティブコードを作って実行 |
clangpp | C++。clang++ でネイティブコードを作って実行 |
感想
- go の整数が長いのが不利だと思ったけど、int32 にしても誤差程度の差しかない。意外。呼出規約的に差がないのかな。
- それにしてもネイティブコードの割に go は遅い。
- 同じ C++ でも、コンパイラによって倍以上違う。なお、この件では gcc / g++ が速いけど、clang が速いこともある。
- ネイティブコードの clangpp より、rosetta2 を経由する、つまりネイティブコードではない rosetta_c の ほうがわずかに速い。
- グラフに含めなかったけど、Java で JIT を off にすると 40秒ぐらいかかる。JIT 偉い。
ということで、ネイティブコードが速いという感想にはあんまりならない。