使用Clang实现更快的代码自动补全

108

我正在研究使用Clang的代码补全机制时的潜在加速方法。下面描述的流程是我在Anders Bakken的rtags中发现的。

翻译单元由监控文件更改的守护程序解析。这是通过调用clang_parseTranslationUnit和相关函数(reparse*dispose*)完成的。当用户在源文件的给定行和列请求完成时,守护进程将最后保存版本的缓存翻译单元和当前源文件传递给clang_codeCompleteAt。(Clang CodeComplete文档)。

CompletionThread::process,第271行传递给clang_parseTranslationUnit的标志为CXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_CacheCompletionResults|CXTranslationUnit_SkipFunctionBodes。 从CompletionThread::process,第305行传递给clang_codeCompleteAt的标志为CXCodeComplete_IncludeMacros|CXCodeComplete_IncludeCodePatterns

clang_codeCompleteAt的调用非常缓慢 - 即使在完成位置是合法成员访问代码的情况下,也需要大约3-5秒才能获得完成结果,这是clang_codeCompleteAt文档中提到的预期用例子集的一部分。按照IDE代码完成标准来看,这似乎太慢了。有没有加速的方法?


8
我很乐意帮助你,但我们需要更具体的细节。例如,提供代码将是一个好的开始。 - raph.amiard
1
Ping。这个问题有进展吗? - Mehrwolf
4
抱歉回复你晚了。我已经尝试了所有8种 CXTranslationUnit_SkipFunctionBodiesCXCodeComplete_IncludeMacrosCXCodeComplete_IncludeCodePatterns 的组合,并没有在我工作的代码库中看到显著的差异。它们的平均完成时间都在4秒左右。我猜这只是因为TUs的大小。CXTranslationUnit_PrecompiledPreamble 可以确保 reparseTU 很快。然而,即使使用了 CXTranslationUnit_CacheCompletionResults,对于我的用例来说,clang_codeCompleteAt 速度非常慢。 - Pradhan
1
@Yakk,回复你的评论,因为几个月前你曾经留言。我还没有解决它,但是对Cameron上面的建议得到了负面结果。 - Pradhan
7
很不幸,您能否在公开可用的翻译单元(例如开源)上重现完成速度变慢的问题?如果我们能够自己重现此问题,那将会很有帮助。因为自动完成内部实际上是注入了一个特殊的代码完成标记然后解析到该点,所以完成速度应该与重新解析大致相同。 - Cameron
显示剩余11条评论
2个回答

6
clang_parseTranslationUnit存在的问题是在第二次调用代码完成时不会重复使用预编译的前导语。计算预编译的前导语需要超过90%的时间,因此您应该尽快允许重复使用预编译的前导语。
默认情况下,第三次调用解析/重新解析翻译单元时才会重用它。
请查看ASTUnit.cpp中的变量“PreambleRebuildCounter”。
另一个问题是这个前导语保存在临时文件中。您可以将预编译的前导语保存在内存中,而不是临时文件中。这将更快速。 :)

太棒了!这听起来像是真正的问题所在。我会看一下并告诉你。谢谢! - Pradhan
好的!让我知道它是否适用于您!如果您有任何问题,请随时问我!!! - GutiMac
@GutiMac,你如何将预编译的前导文件保留在内存中?我花了几个小时查看libclang API,但没有找到任何线索... - Mirek Fidler

4
有时,这种延迟可能是由于网络资源(文件搜索路径上的NFS或CIFS共享或套接字)超时引起的。尝试通过在运行进程之前添加strace -Tf -o trace.out来监视每个系统调用所花费的时间。查看trace.out中带有尖括号的数字,以查找完成时间较长的系统调用。
您还可以监视系统调用之间的时间,以查看哪些文件处理需要太长时间才能完成。为此,请在运行进程之前添加strace -rf -o trace.out。查看每个系统调用之前的数字,以查找长时间的系统调用间隔。从该点向后查找open调用,以查看正在处理的文件。
如果这不起作用,您可以对进程进行分析,以查看它花费大部分时间的位置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接