使用clang更快地完成代码


108

我正在研究使用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代码完成标准,这似乎太慢了。有加速的方法吗?


8
我们很乐意为您提供帮助,但我们需要更多细节。示例代码将是一个很好的起点
raph.amiard 2014年

1
平安 这个问题有什么进展吗?
Mehrwolf 2015年

4
@Cameron对不起,很久之后才能回复您。我想所有的8种组合CXTranslationUnit_SkipFunctionBodiesCXCodeComplete_IncludeMacrosCXCodeComplete_IncludeCodePatterns并没有看到我一起工作的代码库显著差异。每次完成平均耗时约4秒。我想这仅仅是因为TU的大小。CXTranslationUnit_PrecompiledPreamble确保reparseTU非常快。但是,即使使用CXTranslationUnit_CacheCompletionResultsclang_codeCompleteAt在我的用例中也很慢。
Pradhan

1
@Mehrwolf阿克。见上面的评论。
Pradhan

7
嗯,那很不幸。您可以在公众可用的翻译单元(例如开源)上重现完成缓慢吗?如果我们能够自己复制这一点,将会有所帮助。完成应该大致与重新解析一样快,因为它是内部执行的操作(它会注入一个特殊的代码完成令牌并进行解析直到此时)。
卡梅伦

Answers:


6

clang_parseTranslationUnit所具有的问题是第二次重新使用预编译的前导,这被称为代码完成。计算预编译前导花费的时间超过这些时间的90%,因此您应允许在可能的情况下尽快重用预编译的前导。

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

看一下ASTUnit.cpp中的变量'PreambleRebuildCounter'。

另一个问题是此序言保存在临时文件中。您可以将预编译的前导保留在内存中,而不是临时文件中。这样会更快。:)


太棒了!这听起来像是真正的问题。看看这个,让你知道。谢谢!
Pradhan

好!请让我知道这对你有没有用!如果您有任何问题,请随时问我!
GutiMac 2015年

4

有时,这种程度的延迟是由于网络资源超时(文件搜索路径或套接字上的NFS或CIFS共享)引起的。通过给您的运行添加前缀,尝试监视每个系统调用完成的时间strace -Tf -o trace.out。查看尖括号中的数字,以trace.out了解需要很长时间才能完成的系统调用。

您还可以监视两次系统调用之间的时间以查看完成文件处理所需的时间。为此,请在您的运行过程中添加前缀strace -rf -o trace.out。查看每个系统调用之前的号码,以查找较长的系统调用间隔。从那点open往后退以查找调用,以查看正在处理的文件。

如果这样做没有帮助,您可以分析您的过程以了解大部分时间在哪里花费。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.