Goが(Javaと比べて)なぜ遅いのですか?


109

2010年のコンピューター言語ベンチマークゲームからわかるように、

  • Goは平均してCの 10倍遅い
  • GoはJavaより3倍遅い!?

Goコンパイラーが実行用のネイティブコードを生成することを念頭に置いて、これはどのようになりますか?
Goの未熟なコンパイラ?または、Go言語に固有の問題がありますか?

編集:
ほとんどの回答はGo言語の本質的な遅いことを否定し、問題は未熟なコンパイラにあると主張しています。
したがって、フィボナッチ数を計算するためにいくつかの独自のテスト行いました。反復アルゴリズムはsame、C(O3オプションを使用)と同じ速度でGo(freebsd、6g)で実行されます。鈍い再帰的なものは、Go 2 timesでCよりも遅く実行されます(-O3オプションを使用、-O0を使用-同じ)。しかし、ベンチマークゲームのように10倍の減少を見たことはありません。


36
公平に言うと、Cは偽装されたASMであり、Javaは最近、内部でいくつかの深刻な最適化を行っています。
Matthew Scharley、2010

16
おそらく、ベンチマークはGoの長所も反映していません。他のベンチマークは実際にはこれより速いかもしれません。その上、多くの場合、最も重要なのはパフォーマンスではなくコードの読みやすさです。
extraneon

7
@extraneon:同意します。GoはGoogle向けに設計されており、Googleは定期的に200 コアでコードを実行しています。ベンチマークゲームは4つのコアしか使用しないと思います。
イェルクWミッターク

4
@extraneon:私は概ね同意しますが、Goは「結果として得られるプログラムは同等のCまたはC ++コードとほぼ同じ速さで実行される」のように、速度を念頭に置いて具体的に設計されました。
shosti

4
あなたの質問はあまりにも多くを想定しています:「ほとんどの回答はGo言語の本質的な遅さを否定しています」は質問での使用には不適切なフレーズです 質問や発言はありますか?エラーを理解するには、c2.com / cgi / wiki?HostileStudentを参照してください。
クリス

回答:


102

6gコンパイラと8gコンパイラは特に最適化されていないため、生成されるコードはそれほど高速ではありません。

それらは高速に実行され、問題のないコードを生成するように設計されています(少し最適化されています)。gccgoGCCの既存の最適化パスを使用し、Cとのより意味のある比較を提供する可能性がありますが、gccgoはまだ機能が完全ではありません。

ベンチマークの数値は、ほぼ完全に実装の品質に関するものです。ベンチマークが実際に必要としない実行時サポート言語機能を実装が費やしている場合を除いて、それらは言語そのものとはそれほど関係ありません。ほとんどのコンパイルされた言語では、十分に賢いコンパイラーが理論的には不要なものを取り除くことができますが、その機能を使用しないプログラムを書いている言語の実際のユーザーはほとんどいないため、デモを偽装しているところがあります。 。完全に削除せずに物事を邪魔にならないように移動する(たとえば、JITコンパイルされたJavaで仮想呼び出し先を予測する)と、注意が必要になります。

FWIW、ゴーと私自身の非常に些細なテスト私は(基本的には、整数加算のループを)それを見て取っていた、との間の範囲の速い終わりに向かって生成されたコードをgccgo gcc -O0gcc -O2同等のC. Goは本質的に低速ではないため、しかし、コンパイラはまだすべてを行うわけではありません。10分前の言語であることに驚くことはほとんどありません。


7
さらに、コンピューター言語ベンチマークゲームのGoプログラムは、CやJavaのプログラムほど最適化されていない可能性があります。
el.pescado 2010

gcc -O0とgcc -O3の間はどうですか?コンパイラが「すべてを行う」という意図さえあるのでしょうか?
igouy 2010

@igouy:まあ、私はgccgoがガベージコレクションを行うつもりだと確信していますが、現在はそうではありません。gコンパイラーに追加する機能もいくつかあります。たとえば、現在ホストスレッドを特にうまく使用していません(具体的には、ゴルーチンスケジューラーはプリエンプティブではありません)。それを超えて、私はGoogleの計画を知りません、gコンパイラがこれまでに激しく最適化されるかどうか、またはgccgoだけが最適化されるかどうか。
スティーブジェソップ2010

1
@xitrium:Goの意図は、実装を協調的にスケジュールするために必要とされるべきではないということだと思います。たとえばcode.google.com/p/go/issues/detail?id=543を参照してください。これは「無意味なもので、このいわゆるバグを修正するとGo言語の定義と矛盾する」として閉じられていません。 Goの実装は横取りを禁止されています:-)この問題は、Goルーチンがいくつ実行されても、デフォルトではGoが単一のホストスレッドしか使用しなかったという事実によってさらに悪化しました。
スティーブジェソップ2012年

6
答えは今のところ少し古いかもしれません。最近、Go 1.1の最初のベータ版がリリースされました。コンパイルされたプログラムのパフォーマンスが約30%から40%向上すると述べています。誰かがもう一度これらのテストを行ってください。
fuz 2013

51

Go FAQの次のリリースでは、次のようなものが表示されます。

パフォーマンス

GoがベンチマークXでうまく機能しないのはなぜですか?

Goの設計目標の1つは、同等のプログラムのCのパフォーマンスに近づくことですが、一部のベンチマークでは、テスト/ベンチのいくつかを含め、十分に機能しません。最も遅いのは、同等のパフォーマンスのバージョンがGoで利用できないライブラリに依存しています。たとえば、pidigitsは多精度の数学パッケージに依存し、CのバージョンはGoとは異なり、GMP(最適化されたアセンブラーで作成)を使用します。正規表現(regex-dnaなど)に依存するベンチマークは、Goのストップギャップ正規表現パッケージを、PCREなどの高度に最適化された成熟した正規表現ライブラリと本質的に比較しています。

ベンチマークゲームは広範なチューニングによって勝利し、ほとんどのベンチマークのGoバージョンには注意が必要です。同等のCおよびGoプログラムを測定すると(逆補数は1つの例です)、2つの言語がこのスイートで示されるよりも生のパフォーマンスがはるかに近いことがわかります。

それでも、改善の余地があります。コンパイラーは優れていますが、より優れている可能性があります。多くのライブラリーは主要なパフォーマンス作業を必要とし、ガベージコレクターはまだ十分に高速ではありません(たとえ高速であっても、不要なガベージを生成しないように注意することは大きな影響を与える可能性があります)。

そして、最近のメーリングリストスレッドからのコンピュータベンチマークゲームの詳細がいくつかあります。

gccgoでのガベージコレクションとパフォーマンス(1)

gccgoでのガベージコレクションとパフォーマンス(2)

コンピュータベンチマークゲームは単なるゲームであることに注意してください。パフォーマンス測定と容量計画の経験を持つ人々は、現実的および実際のワークロードと同じように注意深く一致します。彼らはゲームをしません。


1
そして、ここで除外した同じスレッドからのいくつかの詳細-groups.google.com/group/golang-nuts/msg/2e568d2888970308
igouy

3
それは、「ベンチマークは壷いる」ことに注意することが重要です-ベンチマークゲームとして公開されていないだけでベンチマーク- shootout.alioth.debian.org/flawed-benchmarks.php
igouy

18
(そしてみんな...)確かにそれは「ゲーム」ですが、これらのベンチマークでGoが最速の2倍遅いだけだとわかったとき、これらのベンチマークは知っているので、私の第一印象は「すごい、Goは速いようです」です。欠陥。それどころか、Rubyが最速の65倍遅いのを目にしたとき、私は「次の並行して数値が集中する試みにRubyを使用しない」と考えています。だから、それは「ゲーム」かもしれませんが、あなたが塩の粒でそれを取るならば、それにはいくらかの真実があります。
SyntaxT3rr0r

キャパシティプランニングには、コストという非常に重要な側面があります。Xボックスまたは2 * Xが必要になるかどうかは、最終的には大きな違いになります。そして、それらについて将来何が実行されるかを予測することはできないため、さまざまなワークロードを確認することをお勧めします。私はこれらのいくつかの実装を確認しましたが、それらはほとんど問題ないことがわかりました。結果は推定のベースとして使用できると思います。
Agoston Horvath

一般に、実際のシステムは、CPUではなくIOによって制約されます。したがって、Goが2xか5xのどちらが遅いかは、フェイルオーバー、ロードバランシング、キャッシング、データベーストポロジーなどの容量計画にほとんど影響を与えません。これが、YouTube規模のアプリがシステムの多くをPythonで実行できる余裕がある理由です。
Sujoy Gupta 2016

34

私の答えは他の誰よりもそれほど技術的ではありませんが、それでも関連性があると思います。囲碁の学習を開始することを決めたとき、コンピューターベンチマークゲームで同じベンチマークを見ました。しかし、正直なところ、Goが十分に高速かどうかを判断する上で、これらすべての総合的なベンチマークは無意味だと思います。

最近、Tornado + TornadIO + ZMQを使用してメッセージサーバーをPythonで作成しました。最初のGoプロジェクトでは、サーバーをGoで書き直すことにしました。これまでのところ、サーバーをPythonバージョンと同じ機能にしたので、私のテストではGoプログラムの速度が約4.7倍向上しました。ちなみに、私はGoでのコーディングを1週間ほどしか行っておらず、Pythonでのコーディングを5年以上続けています。

Goは作業を続けるほど速くなるだけで、実際には、小さな計算ベンチマークではなく、実際のアプリケーションでのパフォーマンスにかかっていると思います。私にとって、Goは明らかに、Pythonで作成できるものよりも効率的なプログラムになりました。それがこの質問に対する私の答えです。


3
Pythonに比べてGoコードを書くのがどれほど遅いと思いますか?
Erik Engheim 2013

7
@AdamSmith-Pythonを7年以上コーディングしていて、Goはほんの少ししかないので、PythonよりもゆっくりとGoコードを書くと思います。しかし、Goと他の静的に型付けされたコンパイル済み言語との比較では、他のバージョンよりも速くGoを書こうと思っています。個人的には、CとC ++の間の速度でPythonのシンプルさに最も近いと感じています
jdi

5
似たような話があります。Goの学習を始めたばかりで、Benchmarks Gameによると、GoはJavaScript V8よりも遅いです。バイナリ演算に重点を置いた私のプログラムは、高度に最適化されたV8 VMの場合よりも、最適化されていないGoコードを使用すると10倍速く実行されることがわかります。Goは多くの操作でCより遅いかもしれませんが、CでWebサイトを作成している人はいません。Goはすでに完全に実行可能なオプションであり、新しいライブラリ、フレームワーク、ツールがポップアップするので、さらに良くなるはずです。
__name__がNoneの場合

1
@ user962247これは気まぐれで誤った包括的な声明です。私は何年もの間Goを書いており、それは非常に速くなっています。可能なすべての合成ベンチマークでC / C ++ / Javaに勝るとは誰も主張していません。しかし、それは一部で勝っています(ベンチマークゲームサイトを参照)。何年も実際にプロダクションGoコードを書いている人からそれを取り出してください。高速で生産的です。
jdi


6

世の中変わったんだよ。

あなたの質問に対する現在の正しい答えは、遅いという考えに異議を唱えることだと思います。お問い合わせの時点では、あなたの判断は正当化されていましたが、それ以来、goはパフォーマンスの面で多くの根拠を得ました。さて、それはまだCほど速くはありませんが、一般的な意味で10倍近くはどこにもありません。

コンピュータ言語ベンチマークゲーム

これを書いている時点で:

source  secs    KB      gz      cpu     cpu load

reverse-complement
1.167x
Go      0.49    88,320  1278    0.84    30% 28% 98% 34%
C gcc   0.42    145,900 812     0.57    0% 26% 20% 100%

pidigits
1.21x
Go      2.10    8,084   603 2.10    0% 100% 1% 1%
C gcc   1.73    1,992   448 1.73    1% 100% 1% 0%

fasta
1.45x
Go      1.97    3,456   1344    5.76    76% 71% 74% 73%
C gcc   1.36    2,800   1993    5.26    96% 97% 100% 97%

regex-dna
1.64x
Go      3.89    369,380 1229    8.29    43% 53% 61% 82%
C gcc   2.43    339,000 2579    5.68    46% 70% 51% 72%

fannkuch-redux
1.72x
Go      15.59   952 900 62.08   100% 100% 100% 100%
C gcc   9.07    1,576   910 35.43   100% 99% 98% 94%

spectral-norm
2x
Go      3.96    2,412   548 15.73   99% 99% 100% 99%
C gcc   1.98    1,776   1139    7.87    99% 99% 100% 99%

n-body
2.27x
Go      21.73   952 1310    21.73   0% 100% 1% 2%
C gcc   9.56    1,000   1490    9.56    1% 100% 1% 1%

k-nucleotide
2.40x
Go      15.48   149,276 1582    54.68   88% 97% 90% 79%
C gcc   6.46    130,076 1500    17.06   51% 37% 89% 88%

mandelbrot
3.19x
Go      5.68    30,756  894 22.56   100% 100% 99% 99%
C gcc   1.78    29,792  911 7.03    100% 99% 99% 98%

ただし、バイナリツリーのベンチマークでは残酷に影響を受けます。

binary-trees
12.16x
Go      39.88   361,208 688 152.12  96% 95% 96% 96%
C gcc   3.28    156,780 906 10.12   91% 77% 59% 83%

現在はJavaと同等ですが、同じこと(サーバー側のネットワーキングアプリ)に使用されているときに、GoよりもJavaよりも高速になるよう明示的に作成されていませんか?
MaxB

1
@MaxBいいえ、Javaよりも高速であることを目標に作成されていません。これは、優れたパフォーマンス、C ++よりも高速なコンパイル、および開発者の生産性を高めるための簡単でネイティブな同時実行性を目標に作成されました。他の言語の実行速度を上回ることは、推進力にはなりませんでした。
jdi 2018年

5

GoのCPUサイクル使用率はそれほど効率的ではありませんが、Go同時実行モデルは、たとえばJavaのスレッドモデルよりもはるかに高速で、C ++スレッドモデルに相当します。

であることに注意してくださいスレッドリングベンチマーク、Goがいた16倍速くするJavaより。同じシナリオで、Go CSPはC ++にほぼ匹敵しましたが、4分の1のメモリしか使用していません。

Go言語の優れた能力は、70年代にTony Hoareによって指定された同時実行モデル、Communicating Sequential Processes、CSPであり、実装が簡単で、同時並行性の高いニーズに適合します。


2

JavaがGoやC ++よりも高速であり、多くの場合Cよりも高速になる可能性があるのには、2つの基本的な理由があります。

1)JITコンパイラ。ランタイムプロファイルに基づいて、OOクラスを使用した場合でも、複数のレベルで仮想関数呼び出しをインライン化できます。これは、静的にコンパイルされた言語では不可能です(ただし、記録されたプロファイルに基づく新しい再コンパイルが役立つ場合があります)。これは、反復アルゴリズムを含むほとんどのベンチマークにとって非常に重要です。

2)GC。GCベースのメモリ割り当ては、mallocと比較してほぼ無料です。また、「無料」のペナルティは、ランタイム全体で償却できます。すべてのガベージを収集する必要がある前にプログラムが終了するため、スキップされることがよくあります。

GC / JVMを効率化する数百人(数千人)の非常に才能のある開発者がいます。「すべてのコードよりも優れたコードを作成できる」と考えるのは愚かです。それは人間の自我の問題です。有能な人間による適切な訓練によって、コンピュータはそれをプログラムした人間よりも優れたパフォーマンスを発揮することを人間は受け入れるのに苦労しています。

ところで、C ++は、OO機能を使用しない場合はCと同じくらい高速ですが、そもそもCでプログラミングするだけにかなり近づいています。

最も重要なのは、これらのテストの「速度の違い」は通常意味がないということです。IOコストはパフォーマンスの違いよりも桁違いに大きいため、解釈された言語であっても、IOコストを最小限に抑える適切な設計が常に成功します。CPUバウンドのシステムはほとんどありません。

最後に、人々は「コンピュータ言語ベンチマークゲーム」を「科学的手段」と呼んでいます。たとえば、nbodyのJavaテストを表示する場合、テストには完全に欠陥があります。同じOS /ハードウェアでテストを実行すると、Javaの場合は約7.6秒、Cの場合は4.7秒-これは妥当です-テストの4倍の速度低下ではありません。これはクリックベイトであり、偽のニュースであり、サイトのトラフィックを生成するように設計されています。

最後の最後のメモとして、Goを使用してテストを実行したところ、7.9秒でした。GoをクリックするとJavaと比較され、JavaをクリックするとCと比較されるという事実は、真面目なエンジニアにとっては重要なことです。

Java、Go、C ++の実際の比較については、https: //www.biorxiv.org/content/10.1101/558056v1のスポイラーアラートを参照してください。Javaは生のパフォーマンスでトップになり、Goはメモリ使用の組み合わせでトップになります。そして壁時間。


違う。C ++はCと同じくらい高速です。特にOOPを使用する場合、それは彼の出生証明書の誤りです。より多くの抽象化(クラスの場合と同様)、実行時のパフォーマンス低下なしで、余分なバイトメモリがゼロ。それがわからない場合は、java、c#、go、pythonなどで

//ところで、C ++は、OOの機能を使用しない場合は// Cと同じくらい高速ですが、そもそもCでのプログラミングに//かなり近づいています。あなたが言うなら、あなたはc ++についてほとんど手掛かりがないので、あなた自身のために、それを使わないでください。cとc ++は魔法と中世の精神を嫌い、本質的に迷信的です、ああ、聞いたように、インターネットで読んでください、それは真実であるに違いありません...

cはc ++の祖先です。多くの人々はまだそれを使用しています... c ++はより良いcであり、価格を支払うことなくより多くのことができます。もちろん、Java、C#、GOの作成者はそれを取得できませんでしたが、取得できましたが、何ができるのでしょうか?既存の(c)コードとの互換性についても同じです。Cコードの実際の海!pythonはいいおもちゃです。楽しんでください。うまくいけばいいのですが、

>> Javaプログラムの30%でのCPU使用率を示します<<いいえ-"1%0%0%100%"。
igouy

1
@igouy私はそれがおそらく私が犯したエラーであることを認めます-負荷を見たとき、私は「システム負荷」の用語で解釈していて、user / system / io / idle-私のミスを想定しており、それはかなりの間違いでした。
ロバートは

1

>見落とされがちな事実は、JITコンパイルは、特に(ランタイム)遅延バインドされた関数またはメソッドの静的コンパイルである可能性があることです。ホットスポットJITは、実行時にインライン化するメソッドを決定し、現在実行中のCPUのキャッシュサイズ/アーキテクチャに合わせてデータレイアウトを調整する場合もあります。一般的にC / C ++は、ハードウェアに直接アクセスすることで構成できます(全体としてはより良いパフォーマンスを示します)。Goの場合、Cに比べて高レベルであるため外観が異なる場合がありますが、現在はランタイム最適化システム/コンパイラーがありません。私の直感は、Go Javaよりも高速である可能性があることを教えてくれます。Goはポインター追跡をそれほど強制せず、より良いデータ構造の局所性を促進するため+必要な割り当ては少なくなります。


1

実際のところ、Goはデザイン時にエレガントで効率的であるだけでなく、実行時にも優れたパフォーマンスを発揮します。重要なのは、適切なオペレーティングシステム、つまりLINUXを使用することです。WindowsとMac OSでのパフォーマンスプロファイリングの結果は、言葉が足りないため、1桁または2桁劣っています。


0

Linuxでは、goランタイムは超高速で、c / c ++に完全に匹敵します。WindowsとUNIXでのGoランタイムは同じリーグに属していません

javaとの比較はそれほど重要ではありません。goはシステム開発とアプリケーション開発の両方を対象としています(javaはアプリケーション開発のみのブルーカラーに似ているため)。詳細は入力しませんが、kubernetesなどがgoで記述されている場合、エンタープライズコンサルタント向けのおもちゃではないことに気づきます。

私はあなたが言及する妥協について一度も言及したグーグルを覚えていません。goは、デザイン、システム、アプリケーションレベルのプログラムを設計するためのシンプルでエレガント、効率的であり、ポインター、効率的なメモリの割り当てと割り当て解除を備えており、実装の継承を誤用しやすいために発生する複雑さを回避し、コルーチンやその他の最新の機能を提供します時間と予算の中で高性能アプリケーションを作成する方法。繰り返しになりますが、Linuxではgoは非常に高速です。これは、Linuxが設計されたものとまったく同じです(そのように非常に満足しています)。


-4

JavaとCはどちらも、データとメソッド(関数)の定義がより明確です。Cは静的に型付けされており、Javaはその継承モデルではそうではありません。これは、データの処理方法がコンパイル中にほぼ定義されることを意味します。

Goは、データと関数の定義がより暗黙的です。組み込み関数はより一般的な性質であり、型階層(JavaまたはC ++など)がないため、Goの速度が低下します。

Go言語に対するGoogleの目標は、実行速度とコーディング速度の間で許容できる妥協点を持つことであることに注意してください。彼らは初期の試みで良いスイートスポットに達していると思います。

コーディング速度が主な利点である動的に型付けされた言語とGoを比較すると、Goの実行速度の利点がわかります。使用したベンチマークでは、Goはperlの8倍、Ruby 1.9およびPython 3の6倍高速です。

とにかく、質問するより良い質問は、プログラミングの容易さと実行速度の妥協点です。私の答えはイエスであり、それは良くなるはずです。


20
「型階層の欠如(JavaやC ++など)はGoに速度の不利益をもたらします」—
エリックカプルン

6
「囲碁は、データと関数の定義がより暗黙的です。」不正解です。それについて明示することなく、型がメソッドを実装する方法を意味しますか?コンパイラーはタイプを検出します-インターフェース・メンバーシップ。これは速いです。「組み込み関数は本質的により一般的です」いいえ、組み込み関数は他のすべてと同様にコンパイルされます。C ++テンプレートでも同じことが起こります。「(JavaやC ++のような)型階層の欠如はGoに速度の不利益をもたらす」-不正解です。型階層はランタイム実行とは何の関係もありません。
Malcolm
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.