clangによるコード補完の高速化


108

clangのコード補完メカニズムを使用しながら、コード補完の潜在的なスピードアップを調査しています。以下に説明するフローは、rtagsで見つけたものです、Anders Bakkenによるでです。

翻訳単位は、変更を監視するデーモンによって解析されます。これは、呼び出されたclang_parseTranslationUnit関数と関連する関数(reparse*dispose*)によって行われます。ユーザーがソースファイルの特定の行と列で完了を要求すると、デーモンは、最後に保存されたバージョンのソースファイルと現在のソースファイルのキャッシュされた変換単位をに渡しますclang_codeCompleteAt。(Clang CodeComplete docs)。

clang_parseTranslationUnitCompletionThread :: process、行271から)に渡されるフラグはCXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_CacheCompletionResults|CXTranslationUnit_SkipFunctionBodesです。clang_codeCompleteAtCompletionThread :: process、行305から)に渡されるフラグはCXCodeComplete_IncludeMacros|CXCodeComplete_IncludeCodePatternsです。

への呼び出しclang_codeCompleteAtは非常に遅くなります。完了場所が正当なメンバーアクセスコードである場合でも、完了を取得するのに約3〜5秒かかりますclang_codeCompleteAt。これは、のドキュメントで言及されている使用目的のサブセットです。これはIDEのコード補完標準では遅すぎるようです。これをスピードアップする方法はありますか?


8
お役に立てれば幸いですが、詳細が必要です。サンプルコードは、開始に適しています
raph.amiard 2014年

1
ping。この問題に進展はありますか?
Mehrwolf 2015

4
@Cameron返信が遅くなってすみません。私は、すべての8つの組み合わせを試してみましたCXTranslationUnit_SkipFunctionBodiesCXCodeComplete_IncludeMacrosCXCodeComplete_IncludeCodePatternsそして私が働いているコードベースに有意差は見ませんでした。それらすべての平均は、完了ごとに約4秒です。これは単にTUのサイズのためだと思います。CXTranslationUnit_PrecompiledPreamble確実reparseTUに非常に高速です。ただし、を使用しても、私のユースケースCXTranslationUnit_CacheCompletionResultsclang_codeCompleteAtは非常に遅くなります。
Pradhan、2015

1
@Mehrwolf Ack。上記のコメントを参照してください。
Pradhan、2015

7
うーん、それは残念です。公開されている翻訳単位(オープンソースなど)で完了の遅さを再現できますか?これを自分で再現できれば助かります。完了は再解析とほぼ同じ速さである必要があります。これは、内部で行うためです(特別なコード補完トークンを挿入し、その時点まで解析するため)。
Cameron

回答:


6

clang_parseTranslationUnitの問題は、プリコンパイルされたプリアンブルがコード補完と呼ばれる2回目に再利用されないことです。プリコンパイルプリアンブルの計算には、これらの時間の90%以上がかかるため、プリコンパイルされたプリアンブルが可能な限り早く再利用されるようにする必要があります。

デフォルトでは、翻訳単位を解析/再解析するために呼び出される3回目に再利用されます。

ASTUnit.cppでこの変数「PreambleRebuildCounter」を確認してください。

その他の問題は、このプリアンブルが一時ファイルに保存されることです。一時ファイルの代わりに、プリコンパイルされたプリアンブルをメモリに保持できます。それはより速くなります。:)


驚くばかり!これは本当の問題に到達したように聞こえます。これを見て、お知らせします。ありがとう!
Pradhan

OK!それがあなたのために働くかどうか私に知らせてください!質問がある場合は、遠慮なく私に聞いてください!!!!
GutiMac、2015年

4

この大きさの遅延は、ネットワークリソース(ファイル検索パスまたはソケット上のNFSまたはCIFS共有)のタイムアウトが原因で発生する場合があります。実行するプロセスの先頭にを付けて、各システムコールが完了するまでの時間を監視してみてくださいstrace -Tf -o trace.outtrace.out完了までに時間がかかるシステムコールについては、山かっこ内の数字を確認してください。

システムコールの時間監視して、ファイルのどの処理が完了するまでに時間がかかりすぎているかを確認することもできます。これを行うには、実行するプロセスの前にを付けstrace -rf -o trace.outます。各システムコールの前に番号を見て、長いシステムコール間隔を探します。その時点から後方に移動して、open処理中のファイルがどれかを確認するための呼び出しを探します。

これで効果がない場合は、プロセスのプロファイルを作成して、ほとんどの時間を費やしている場所を確認できます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.