使用 clang 更快地完成代码

Posted

技术标签:

【中文标题】使用 clang 更快地完成代码【英文标题】:Faster code-completion with clang 【发布时间】:2015-01-15 08:23:35 【问题描述】:

我正在研究使用 clang 的代码完成机制时潜在的代码完成加速。下面描述的流程是我在 Anders Bakken 的 rtags 中找到的。

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

传递给clang_parseTranslationUnit(来自CompletionThread::process, line 271)的标志是CXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_CacheCompletionResults|CXTranslationUnit_SkipFunctionBodes。传递给clang_codeCompleteAt(来自CompletionThread::process, line 305)的标志是CXCodeComplete_IncludeMacros|CXCodeComplete_IncludeCodePatterns

clang_codeCompleteAt 的调用非常慢 - 即使完成位置是合法成员访问代码(文档中提到的预期用例的子集),也需要大约 3-5 秒才能获得完成的clang_codeCompleteAt。根据 IDE 代码完成标准,这似乎太慢了。有没有办法加快速度?

【问题讨论】:

我很乐意为您提供帮助,但我们需要更多细节。示例代码将是一个很好的开始 平。这个问题有进展吗? @Cameron 很抱歉长时间延迟回复您。我尝试了CXTranslationUnit_SkipFunctionBodiesCXCodeComplete_IncludeMacrosCXCodeComplete_IncludeCodePatterns 的所有 8 种组合,并没有发现我正在使用的代码库有显着差异。所有这些平均每完成大约 4 秒。我想这只是因为 TU 的大小。 CXTranslationUnit_PrecompiledPreamble 确保 reparseTU 非常快。然而,即使使用CXTranslationUnit_CacheCompletionResultsclang_codeCompleteAt 对我的用例来说也非常缓慢。 @Mehrwolf 确认。见上面的评论。 嗯,这很不幸。您能否重现对公众可用的翻译单元(例如开源)的完成速度慢?如果我们能够自己复制它会有所帮助。完成应该与重新解析大致一样快,因为这就是它在内部所做的(它注入一个特殊的代码完成令牌并解析到那个点)。 【参考方案1】:

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

您还可以监控系统调用之间的时间,以查看文件的哪些处理需要很长时间才能完成。为此,请在您运行的进程前加上strace -rf -o trace.out。查看每个系统调用之前的数字以查找较长的系统调用间隔。从该点向后查找open 调用以查看正在处理的文件。

如果这没有帮助,您可以profile您的进程以查看其大部分时间花在哪里。

【讨论】:

【参考方案2】:

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

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

查看 ASTUnit.cpp 中的这个变量“PreambleRebuildCounter”。

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

【讨论】:

太棒了!这听起来像是解决了真正的问题。会看看这个,让你知道。谢谢! 好的!请让我知道这对你有没有用!如果您有任何问题,请随时问我!!!!

以上是关于使用 clang 更快地完成代码的主要内容,如果未能解决你的问题,请参考以下文章

Clang vs GCC - 产生更快的二进制文件? [关闭]

C++学习(三四八)CLang GCC

我可以通过使用多个线程来更快地分配内存吗?

在 CLion 中使用 clang 格式

缓存型 C++ 编译器 Zapcc 开源,号称比 Clang 更快

我可以在源代码之外使用 Clang 库吗?