別のCプログラマーから、いくつかの異なる.cファイルと.hファイルで大きなアプリケーションを作成し、それらを一緒にコンパイルするように言われました。彼らはそれがより速く動くと言います。
マルチファイルアプリケーションはシングルファイルアプリケーションよりも速く実行されますか?もしそうなら、何がそれをより速く動かすのですか?また、マルチファイルプログラミングには他にどのような利点がありますか?
マルチファイルCプログラムはどのプラットフォームに影響しますか?
大規模で複雑なシステムを作成するときに複数のファイルを使用することには、多くの技術的な理由があります。複数のファイルを使用する最善の理由に直面しても、それらはすべて無意味です。
読みやすさ。
1つのファイルに常駐するコードを作成するとき、システムのこの部分がどのように機能するかを理解するために理解する必要があることを示しています。このファイルにないすべての詳細は抽象化されており、他のファイルに頭を突っ込むことなく、ここで何が起こっているのかを理解できるようにするための適切な名前で表されます。
私がそれに失敗した場合、私はくだらないコードを書いたので、あなたはそれを私に呼びかけるべきです。そのようなケースでは、複数のファイルがほとんど役に立ちません。
その配慮がなければ、プログラム全体を1つのファイルに書き込むことができます。 CPUは気にしません。彼らがそれを読み込もうとするとき、それはちょうど人間を惨めにするでしょう。
従来の技術的な理由は、システム全体を再デプロイすることなく変更できる独立してデプロイ可能なユニットにコードを分割することです。ソフトウェアが多くのチップに焼き付けられていて、変更する必要があるという理由だけですべてのチップを捨てたくない場合など、それが非常に重要な場合があります。
独立してデプロイ可能であることは、変更したものを再コンパイルするだけでよいので、コンパイルをより速く行えることも事実です。
とはいえ、そうした場合でも、最大の利点は、読者が一度に頭に抱くと期待することを制限する境界を作成することだと私は主張します。
TL; DR複数のファイルプログラムを理解するために複数のファイルを調べ続ける必要があるために煩わしい場合は、単に悪い名前の不完全に抽象化されたコードを見ているだけです。それはそう感じるべきではありません。各ファイルは、1つの観点から1つのストーリーを伝える必要があります。
質問はと同じカテゴリに分類されます。なぜ、建物は1つの岩ではなく、たくさんのレンガでできているのですか?
回答:
これは私の頭の上からです-確かにより多くの利点があります。
他の回答は問題ありませんが、欠けているのは実際の技術的な制限です。
たとえば、日中の仕事のアプリケーションのすべてのコードを1つのファイルに実際に保存することはできません。これは、一般的なファイルシステムのファイルサイズ制限よりも大きくなります。そのようなサイズの場合、そのコードの構文ツリーがさらに大きくなるため、エディター、コンパイラー、およびリンターで大混乱を引き起こします。そして、一度に数十のギグのテキストを処理しようとするソース管理および差分ツールにアクセスします。 Cで作業しているため、実際のバイナリサイズについても考慮する必要があります。ほとんどのOSには、ファイルシステムのサイズ制限とは別の実行可能サイズ制限があります。
もちろんこれは異常値です。複数のファイルは、主にプログラマーの生活を楽にするためのものですが、これにより、「大規模アプリケーション」が何を伴う可能性があるかをよりよく理解できると思います。
私はいくつかの異なるファイルで大きなアプリケーションを書くように言われました。彼らはそれがより速く動くと言います。何が速くなるのですか?
また、マルチファイルアプリケーションは、実際にはシングルファイルアプリケーションよりも速く実行されますか
Cでは、マルチソースファイルアプリケーションがより高速に実行されると想定する理由はなく、それがわずかに遅くなるいくつかの理由があります。複数のファイルの使用は、開発者の便宜のためです。
コンパイラに渡される前に1つの巨大なファイルに結合される複数のファイルを書き込むことができるビルドシステムもあります。 これは「ユニティ」または「合併」ビルドと呼ばれることがあります。
主な理由はインライン化です:関数の呼び出しを関数のコピーで置き換えます。 Cは通常、リンカーがそうするように構成されていない限り、異なるソースファイルからの関数をインライン化しません。この機能は、GCCでは「リンク時最適化」と呼ばれています。
他のコメンテーターは、プログラムの未使用のビットを読み込まないという考えに言及しています。ただし、ソースファイルによって提供される関数のグループ化は、実行可能ファイルに保存されない場合があります。 "overlay" システム(ほとんど使用されなくなった)を使用していない場合、または一部の機能を「プラグイン」に分離している場合を除きます。
Linuxおよび仮想メモリを備えたその他のシステムでは、オペレーティングシステムがプログラムの未使用部分を独自にアンロードできます。
文字列定数の重複排除のようなものからいくつかの小さな利点もあります。ここでも、リンカーにこれを処理させることができますが、デフォルトではオンになっていない場合があります。
ビルド速度の問題は検討する価値があります。プログラムをN個のファイルに分割した場合、Nは100〜10,000の範囲になる可能性があります。1つのファイルをコンパイルする方が、通常、すべてのNファイルをコンパイルするよりもはるかに高速です。ただし、場合によっては、すべてのNファイルを1つの巨大なファイルに収集する方が、それらを個別にコンパイルするよりも高速です-コンパイラーをクラッシュさせない場合。これは、コンパイル時間が非常に長くなる可能性があるC++ではより重要になる傾向があります。
実際には、開発者はソースファイルを扱いやすくするために分割します。意見はさまざまですが、ファイルの分割を検討するには、1,000行が適切なガイドライン番号です。
プログラムに複数のファイルを使用する利点は数多くあります。たとえば、
この記事 でより多くの引数を見つけることができます。
どういうわけか誰も言及していない複数のファイルを使用するもう一つの重要な理由:
チームでソフトウェア開発プロジェクトに取り組む場合、Gitなどのバージョン管理システムを使用することは非常に一般的です。 VCSが直面する大きなハードルの1つは、複数の作成者の作業をマージすることです。あなたと別の開発者が同じファイルで同時に作業する場合、最終的には作業をマージする必要があります。場合によっては、同じファイルの同じ部分を両方とも編集する可能性がありますマージの競合:VCSが変更をマージする方法を自動的に決定できず、人間がしなければならない状況手動で行います。
すべてのコードが1つのファイルにある場合、マージの競合のリスクが高まります。コードに取り組んでいる誰もが同じファイルで作業しています。これにより、同じコードを同時に編集したり、他の方法で互いに足を踏み入れたりする可能性が高くなります。ファイルの別の部分で作業している誰かでさえ、あなたの作業を妨害する何かをうっかりしてしまうかもしれません。たとえば、ファイル全体の自動フォーマット、編集中の関数の名前の変更、コードの再編成、関数の移動などを行います。
コードを複数のファイルに分割された論理システムに分割すると、複数の人が同時に同じファイルで作業することによって生じるマージ競合のリスクが軽減されます。また、各ファイルのコードが少ないほど競合が小さくなり、解決が容易になるため、マージの競合を簡単に解決できます。
これは、残念ながら以前に遭遇した最悪のシナリオです。TomとSallyが作業している10,000行のファイルがあります。彼らはそれぞれ数時間かけて、コードのさまざまな部分を大幅に編集しています。ある時点で、トムはインデントの間違いに気づき、ファイル全体のインデントや改行などを変更する「自動フォーマット」ホットキーを習慣的に押します。その後、両者がコードをコミットしようとすると、トムの自動フォーマットがファイル全体のコードのほぼすべての行を変更し、VCSが変更をマージする方法を理解できないため、マージの競合が発生します。トムかサリーのどちらかが時間時間を費やして、10,000行のコードを手動でマージする必要があります。コードが複数のファイルに分割されていた場合、それらにはまったく競合がなかった可能性があり、たとえ分割されてもコードベース全体には影響しませんでした。
一般に、状況によって異なります。 JavaScriptの他の回答に加えて、pythonおよびインポートされたファイルがおそらく一度は認識されない他の言語が読み込まれるのは1回だけであることを認識していません。150000語のファイルをインポートする必要があるとしましょう。変数(またはデータ構造)に読み込むのに約1秒必要です。次に、このファイルを使用して、Wordがこれらの150000エントリにあるかどうかを確認します。また、このプロセス全体を1000回再実行する必要があります。つまり、約1000です。 15秒のエントリファイルを別のファイルから変数としてインポートすると、1000ステップのプロセス全体で約1秒かかります。
ただし、残りの回答は、質問に対してより重要な理由を提供することを覚えておいてください。
Jump-to-Definitionなどの複雑なコードナビゲーションツールがある場合でも、ファイルとフォルダーのツリーでプロジェクトを整理すると、新しい開発者のオンボーディングが容易になります。機能の作業を開始するために必要なファイルを見つけやすくなります。
「より速い」問題に関しては、ほとんどの最新のコンパイラーはLTOをサポートしているため、個別のコンパイル単位(デバッグ中のコンパイルの高速化)を使用しても、結果の実行可能ファイルはLTOがオンになっていると同じ速度で実行されます。
その多くは次のようになります。
多くの場合、IDEがそのファイル内を移動し、ファイルのさまざまな部分を表示するのを簡単に支援できれば、ディスク上の1つの実際のファイルにすべてのコードを含めることはまったく問題ありません。並んで。