私はTDDスタイルのC#でのコーディングに慣れていました。コードの小さなチャンクを記述または変更し、ソリューション全体を10秒で再コンパイルして、テストを再実行しました。簡単...
この開発方法論は、C++コーディングに戻る必要があった昨年まで、私にとって数年は非常にうまく機能し、それ以来、私の生産性が劇的に低下したように感じています。言語としてのC++は問題ではありません-私はC++開発者の経験をかなり積んでいました...しかし過去には。
私の生産性は小規模なプロジェクトでも問題ありませんが、プロジェクトのサイズが大きくなると悪化し、コンパイル時間が10分以上になると本当に悪くなります。そして、エラーが見つかった場合は、コンパイルを再度開始する必要があります。
したがって、私は小さなチャンクでは(以前のように)受け入れられないと結論付けました-コードを手動で(高速C#コンパイラーに依存せずに)レビューするときに、1時間ほどコーディングの古い習慣に身を任せるにはどうすればよいですか? 、ユニットテストを数時間に1回だけ再コンパイル/再実行します。
C#とTDDを使用すると、進化的な方法でコードを書くのが非常に簡単でした。何十回も繰り返した後、最初にどんながらくたも良いコードになってしまったのですが、それだけでは機能しません(遅いコンパイルでは)環境)。
いくつかのことが頭に浮かびます。
分散コンパイルを利用します。これは、GCC( "distCC"?)またはVC( Xoreax 'IncrediBuild は正確ではありませんが、1セントを費やすだけの価値があります。)で実行できます。).
プロジェクトを分割して動的に読み込まれるライブラリに入れ、それらへの依存関係を最小限に抑えるように注意してください。小さい実行可能ファイルは、はるかに速くリンクします。
大きなアプリケーション全体ではなく、小規模なテストプロジェクトに対してプログラムします。
テンプレートメタプログラミングを使用して、コンパイル時にアルゴリズムを実行します。はい、実際にはコンパイル時間が増加しますが、テストに必要なターンアラウンドも減少します。正常にコンパイルされれば、完了です。
hardwareに投資します。 (マシンまたはその他の)より多くのCPUカーネルは、分散コンパイルに不思議に思うでしょう。大量のメモリと高速ディスク(HDDではなくSSD)は、多くのことに役立ちます。 64ビットシステムでわいせつな量のRAMを使用している場合、RAMディスクでコンパイルすると、信じられないほどの速度向上が得られる可能性があります。
他の人がまだ言及していないもう1つの技術的な解決策は、通常のハードドライブの代わりにソリッドステートドライブに切り替えることです。私が取り組んだ以前のプロジェクトでは、SSDはビルド時間を30分から3の範囲に短縮しました。
もちろん、それらは高価です。上司のために、1回限りの投資の価格に対する開発者の失われた時間の価格を計算します。投資はおそらく数ヶ月で元が取れます。
より多くの計画、大きなチャンクでのコード、ユニットテストの代わりに統合テストを記述し、ビルド+テストスイートを一晩実行します。
長いコンパイル時間は時々問題になりますが、すでに述べたモジュール化はそれを(ほとんど)克服するのに役立ちます。
コンパイルがまったくできない環境では、さらに深刻な問題が発生しています。コードの変更はすべて、別の大陸の別の部門に提出して、テスト/開発環境に適用する必要があります。このプロセスには、数日かかる場合があります。
私は現在、このような環境で作業しており、このシステムでは、変更の最初のバージョンをインストールするだけで、1週間以上の費用がかかります(プロジェクトの予算がなくなるまでに合計4週間しかかかりません)。 (そして、ファイルの一部がアプリケーションサーバーによって取得されない原因となるミスを犯したため、さらに数日間の遅延を検討しています)。現在、マイナーな変更(たとえば、エラー状態の欠落など、修正が必要なものをテストで見つけた)により、1日以上の遅延が発生する可能性があります。
このような状況では、コードをコンパイルする前に、エラーがないことをできる限り確認する必要があります。まるでメインフレームのプログラミングに戻ったような気がします。すべてのコンパイルおよびテスト作業に1か月あたり5分のCPU時間を利用できました。
ビルドに長い時間がかかったことを簡単に思い出すことができます。いくつかの緩和策:
コンパイルに10分以上かかりますか?マジ?
IDE増分ビルドを行うEclipseなど)を使用していますか?そうでない場合は、おそらくそうであるはずですが、基本的なコンパイルは分単位ではなく秒単位で行われます。
あるいは、変更をテストするためにアプリ全体を構築する必要がある統合に関する話ですか?もしそうなら、完全なビルドを行う前に、小さなテストを見て、主要なバグがコードにないことを確認してください。
まず、そもそもコンパイルに時間がかかるのはなぜですか?
これでもすべてビルド時間が遅い場合は、問題を解消してください。多数の小さなテストプロジェクトを作成し、それぞれ個別に作業します。フレッシュチェックアウトを実行し、すべてをビルドし、すべてのユニットテストを自動的に実行する自動化された夜間ビルドシステムがあることを確認します。
最後に、変更をテストするのにまだ長い時間がかかる場合は、変更についてさらに検討してください。テストする前に、バージョン管理システムで差分を作成し、すべての変更を注意深く確認してください。つまり、これは組み込みシステム開発と非常によく似ており、テストのターンアラウンドタイムが長く、システムの状態を検査する能力が制限されます。
これは私に別の考えを導きます:ロギングを使用するようにコードを計測します。この方法では、何回も再構築して再実行しなくても、問題が何であるかを確認できる場合があります。
おそらく、多面的なアプローチが必要です。
1)より高速なビルドシステム。できるだけ多くのコア/ RAM /高速ディスク。大規模なC++プロジェクトの場合、ディスクがリミッターであることが多いので、高速なものを使用してください。
2)プロジェクトのさらなるモジュール化。変更によってすべての完全な再コンパイルが簡単に行われないように、要素を分割します。率直に言って、プロジェクトの一部を残りの部分から完全に分離できるように、できるだけ多くの基本的なものを個別のdll/soファイルにプッシュします。
3)環境に応じて、増分ビルド/分散ビルド/キャッシング。一部のシステムでは、distcc(分散ビルド)およびccache(部分的にビルドされたもののキャッシュ)により、コンパイル時間を大幅に節約できます。
4)ビルドが十分に並列化できることを確認します。特にMakefile環境では、並列ビルドを実行できないようにMakefileを誤って設定した状況に陥ることは難しくありません。
広範なロギングと内部検証は、長いターンアラウンドタイムに役立ちました。ビルドが完了すると、1回の実行で、可能性のある大量の問題が一度に明らかになります。
かなり複雑なアルゴリズムや簿記を扱う場合、「実際の」アルゴリズムと並行して非常に簡略化されたバージョンを含めると役立ちます。どの実行でも、役立つ参照データが含まれています。
@sbiと@Michael Kohneが言ったこと。
ビルドプロセス自体に時間とエネルギーを費やします。かつて、フルビルドに1時間以上かかる風格のある成熟した製品がありました。ビルドの依存関係の主張を修正するために多くの時間と労力が費やされ、その後、実際の依存関係を修正または削減しました。ビルド時間は約30分に短縮されました。
ビルドツールを変更すると、それはさらに低下しました。マルチパートプロジェクトの場合、「scons」はリンクを行う前にすべてのコンパイルを実行できます。複数のmakefileを使用する「make」は、そのプロジェクトのリンクの前に1つのプロジェクトのコンパイルを行い、次に進みます。
そのため、個々のコンパイルコマンドはすべて、大規模な並列処理を行うことができます。遅いマシンでは「distcc」、マルチコアマシンではmake/scons -j8。これにより、ビルド全体がほんの数分になりました。
別の観点から、自動化された夜間のビルドプロセスを作成します。そうすることで、問題のあるものがソースリポジトリにコミットされた場合、最初に作業に着手し、問題を確認して修正することで、複数の人が複数の失敗したビルドを(再)実行できないようにすることができます。