私は、ガベージコレクションが(理論的には)手動のメモリ管理よりも高速である可能性があることを、多くの場所で読んでいます(実際、自分で書きました)。
ただし、表示することは、伝えることよりもはるかに困難です。この効果が実際に作用することを示すコードを
実際に見たことはありません。
このパフォーマンスの利点を実証するコードを誰かが持っていますか(またはどこにあるかを知っていますか)?
私は、ガベージコレクションが(理論的には)手動のメモリ管理よりも高速である可能性があることを、多くの場所で読んでいます(実際、自分で書きました)。
ただし、表示することは、伝えることよりもはるかに困難です。この効果が実際に作用することを示すコードを
実際に見たことはありません。
このパフォーマンスの利点を実証するコードを誰かが持っていますか(またはどこにあるかを知っていますか)?
回答:
http://blogs.msdn.com/b/ricom/archive/2005/05/10/416151.aspxを参照し、すべてのリンクをたどってRico Mariani対Raymond Chen(Microsoftの非常に有能なプログラマー)が決着をつける。レイモンドは管理されていないものを改善し、リコは管理されたもので同じことを最適化することで対応します。
基本的に最適化の労力はゼロで、管理バージョンはマニュアルよりも何倍も早く起動しました。最終的にマニュアルはマネージドを打ち負かしましたが、ほとんどのプログラマーが行きたくないレベルに最適化することによってのみです。すべてのバージョンで、マニュアルのメモリ使用量は管理対象よりも大幅に優れていました。
swap
)ではないということは難しいですが、おそらく非常に簡単に性能面があなたを得るでしょう...
経験則では、無料のランチはありません。
GCは、手動のメモリ管理の頭痛を取り除き、ミスをする可能性を減らします。特定のGC戦略が問題の最適な解決策である状況がいくつかありますが、その場合、それを使用してもペナルティはありません。しかし、他のソリューションがより高速になる他のものがあります。低いレベルから高い抽象化をいつでもシミュレートできますが、他の方法ではできないため、一般的な場合、高い抽象化が低い抽象化よりも速くなる方法がないことを効果的に証明できます。
GC は、手動メモリ管理の特殊なケースです
手動でより良いパフォーマンスを得るには、多くの作業やエラーが発生する可能性がありますが、それは別の話です。
GCが手動の方法よりも無限に効率的である人工的な状況を構築するのは簡単です-ガベージコレクターに「ルート」が1つだけあり、すべてがガベージであるように調整するだけで、GCの手順は即座に完了します。
考えてみると、それはプロセスに割り当てられたメモリをガベージコレクションするときに使用されるモデルです。プロセスは死に、メモリはすべてゴミになり、完了です。実用的な用語であっても、トレースを残さずに開始、実行、および終了するプロセスは、永久に開始して実行するプロセスよりも効率的です。
ガベージコレクションを使用する言語で記述された実用的なプログラムの場合、ガベージコレクションの利点は速度ではなく、正確性と単純さです。
abort()
は、プログラムが終了する前にC ++を呼び出すようなものです。これは無意味な比較です。あなたはガベージコレクションさえしていません、ただメモリリークをさせているだけです。最初からガベージコレクションを行っていない場合、ガベージコレクションの速度が速い(または遅い)とは言えません
GCは単なるメモリ管理戦略ではありません。また、言語およびランタイム環境の設計全体に要求があり、コスト(および利点)がかかります。たとえば、GCをサポートする言語は、ガベージコレクターからポインターを非表示にできない形式にコンパイルする必要があります。通常は、慎重に管理されたシステムプリミティブを除き、ポインターを構築できません。もう1つの考慮事項は、GCが完了するまで実行を許可する必要があるいくつかのステップを課すため、応答時間の保証を維持することの難しさです。
したがって、ガベージコレクションされた言語があり、同じシステムで手動で管理されたメモリと速度を比較する場合、ガベージコレクションを使用していない場合でも、ガベージコレクションをサポートするためにオーバーヘッドを支払う必要があります。
より速いのは疑わしい。ただし、ハードウェアがサポートされている場合、超高速、感知できない、または高速になる可能性があります。LISPマシン用のそのような設計はずっと前にありました。メインCPUがそこにあることを知らないように、GCをハードウェアのメモリサブシステムに組み込みました。後の多くの設計と同様に、GCは一時停止をほとんどまたはまったく必要とせずにメインプロセッサと同時に実行されました。より近代的な設計は、専用のプロセッサと一時停止のないGCを使用するJVMよりも高速にJavaコードを実行するAzul Systems Vega 3マシンです。GC(またはJava)の速度を知りたい場合は、Googleを使用してください。
私はこれについてかなりの仕事をして、ここでそのいくつかを説明しました。Boehm GCをC ++でベンチマークし、C ++で記述されたカスタムマーク領域GCと、リストベースのn-queensソルバーを実行するOCamlのストックGC malloc
を使用して割り当てますが、解放はしませんfree
。OCamlのGCはすべてのケースで高速でした。C ++およびOCamlプログラムは、同じ割り当てを同じ順序で実行するように意図的に作成されています。
もちろん、プログラムを書き換えて、64ビット整数のみを使用し、割り当てを使用せずに問題を解決できます。より高速であると、演習のポイントが無効になります(これは、C ++で構築されたプロトタイプを使用して取り組んでいた新しいGCアルゴリズムのパフォーマンスを予測することでした)。
私は長年、業界で実際のC ++コードをマネージ言語に移植してきました。ほとんどすべてのケースで、パフォーマンスの大幅な向上が見られましたが、その多くは、GCが手動のメモリ管理に勝っていることによるものと思われます。実用的な制限は、マイクロベンチマークで達成できることではなく、期限とGCベースの言語が非常に大きな生産性の改善を提供する前に達成できることです。私は今でも組み込みデバイス(マイクロコントローラー)でCとC ++を使用していますが、それも今では変わりつつあります。
List.filter
同様にカスタムを実際に使用する必要があります。しかし、はい、確かに、一部のRC操作は省略できます。しかし、私が実際に目にする最大の問題は、人々が大規模な産業用コードベースでそのような最適化を手作業で実行する時間がないことです。
shared_ptr
並行性のバグを修正するためだけにすべてを変換する人を見てきました。コードは非常に遅くなりますが、今は動作します。
このような例には、手動によるメモリ割り当てスキームが必ず必要です。
最高のガベージコレクターを想定してくださいGC
。内部には、メモリを割り当てるメソッド、解放できるメモリを決定するメソッド、最終的に解放するメソッドがあります。一緒にこれらのすべてよりも時間がかかりGC
ます。いくつかの他のメソッドで時間を費やしていGC
ます。
ここで、と同じ割り当てメカニズムを使用し、GC
そのfree()
呼び出しがと同じメソッドによって解放されるメモリを確保するだけの手動アロケータを考えてみましょうGC
。スキャンフェーズはなく、他の方法もありません。必然的に時間がかかりません。
free
バッチも収集できます。(唯一の理由は、リスト・トラバーサル自体の場合はもちろんの基準を満たすすべての項目を削除すると、まだO(N)である)
free
GCは、まだいくつかの状況で先に出てくることができますが、各メモリ項目は、それに関連付けられた旗を持っていた場合は、バッチ・コレクトモードで動作することができます。N個のセットからL個の異なるアイテムを識別するM個の参照がある場合、参照が存在しないすべての参照を削除して残りを統合する時間は、O(N)ではなくO(M)です。Mの追加スペースがある場合、スケーリング定数は非常に小さくなります。さらに、非スキャンGCシステムのコンパクト化には...が必要です。