私は、clangのコード補完メカニズムを使用しながら、潜在的なコード補完の高速化を調査しています。以下に説明するフローは、Anders Bakkenが rtags で見つけたものです。
翻訳単位は、ファイルの変更を監視するデーモンによって解析されます。これは、clang_parseTranslationUnit
および関連する関数(reparse*
、dispose*
)によって呼び出されます。ユーザーがソースファイルの特定の行と列で完了を要求すると、デーモンは、ソースファイルの最後に保存されたバージョンと現在のソースファイルのキャッシュされた翻訳単位をclang_codeCompleteAt
に渡します。 ( Clang CodeComplete docs )。
clang_parseTranslationUnit
( CompletionThread :: process、行271 )から渡されるフラグはCXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_CacheCompletionResults|CXTranslationUnit_SkipFunctionBodes
です。 clang_codeCompleteAt
( CompletionThread :: process、305行目 )から渡されるフラグはCXCodeComplete_IncludeMacros|CXCodeComplete_IncludeCodePatterns
です。
clang_codeCompleteAt
への呼び出しは非常に遅い-完了場所が正当なメンバーアクセスコードである場合でも、完了を取得するのに約3〜5秒かかります。 clang_codeCompleteAt
。これはIDEコード補完標準によって遅すぎるようです。これを高速化する方法はありますか?
Clang_parseTranslationUnitの問題は、プリコンパイルされたプリアンブルがコード補完と呼ばれる2回目に再利用されないことです。プリコンパイルプリアンブルの計算には、これらの時間の90%以上がかかるため、プリコンパイルされたプリアンブルができるだけ早く再利用されることを許可する必要があります。
デフォルトでは、変換ユニットの解析/再解析のために呼び出される3回目に再利用されます。
ASTUnit.cppのこの変数「PreambleRebuildCounter」を見てください。
他の問題は、このプリアンブルが一時ファイルに保存されることです。一時ファイルではなく、プリコンパイルされたプリアンブルをメモリに保存できます。速くなります。 :)
この大きさの遅延は、ネットワークリソース(ファイル検索パスまたはソケット上のNFSまたはCIFS共有)のタイムアウトが原因である場合があります。実行するプロセスの前にstrace -Tf -o trace.out
を付けることにより、各システムコールが完了するまでの時間を監視してみてください。完了するまでに長い時間がかかるシステムコールについては、trace.out
の山括弧内の数字を見てください。
また、時間betweenシステムコールを監視して、ファイルのどの処理が完了するのに時間がかかりすぎるかを確認することもできます。これを行うには、実行プロセスの前にstrace -rf -o trace.out
を付けます。各システムコールの前に番号を見て、長いシステムコール間隔を探します。 open
呼び出しを探してそのポイントから後方に移動し、どのファイルが処理されていたかを確認します。
これが役に立たない場合は、 profile プロセスでほとんどの時間を費やしている場所を確認できます。