108

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

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

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 のコード補完基準では遅すぎるようです。これを高速化する方法はありますか?

4

2 に答える 2

6

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

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

ASTUnit.cpp のこの変数 'PreambleRebuildCounter' を見てください。

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

于 2015-06-22T20:04:32.733 に答える
4

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

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

これで問題が解決しない場合は、プロセスをプロファイリングして、最も多くの時間を費やしている場所を確認できます

于 2015-06-04T17:54:49.977 に答える