108

I am investigating potential code-completion speedups while using clang's code-completion mechanism. The flow described below is what I found in rtags, by Anders Bakken.

Translation units are parsed by a daemon monitoring files for changes. This is done by called clang_parseTranslationUnit and related functions(reparse*, dispose*). When the user requests a completion at a given line and column in a source file, the daemon passes the cached translation unit for the last saved version of the source file and the current source file to clang_codeCompleteAt. (Clang CodeComplete docs).

The flags passed to clang_parseTranslationUnit(from CompletionThread::process, line 271) are CXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_CacheCompletionResults|CXTranslationUnit_SkipFunctionBodes. The flags passed to clang_codeCompleteAt(from CompletionThread::process, line 305) are CXCodeComplete_IncludeMacros|CXCodeComplete_IncludeCodePatterns.

The call to clang_codeCompleteAt is very slow - it takes around 3-5 seconds to obtain a completion even in the cases where the completion location is a legitimate member access code, a subset of the intended use case mentioned in the documentation of clang_codeCompleteAt. This seems way too slow by IDE code-completion standards. Is there a way of speeding this up?

4

2 回答 2

6

clang_parseTranslationUnit 的问题是预编译的前导码没有被第二次重用,这称为代码完成。计算预编译前导码需要超过这些时间的 90%,因此您应该允许尽快重用预编译的前导码。

默认情况下,它在第三次被调用来解析/重新解析翻译单元时被重用。

查看 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 回答