使用 clang 更快地完成代码

Faster code-completion with clang

本文关键字:代码 clang 使用      更新时间:2023-10-16

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

转换单元由监视文件的守护程序解析更改。这是通过调用clang_parseTranslationUnit和相关函数(reparse*dispose*)来完成的。当用户请求完成源文件中给定的行和列时,守护程序会将上次保存的源文件版本和当前源文件的缓存翻译单元传递给clang_codeCompleteAt。(叮当代码完整文档)。

传递给clang_parseTranslationUnit的标志(来自 CompletionThread::p rocess,第 271 行)CXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_CacheCompletionResults|CXTranslationUnit_SkipFunctionBodes 。传递给clang_codeCompleteAt的标志(来自 CompletionThread::p rocess,第 305 行)CXCodeComplete_IncludeMacros|CXCodeComplete_IncludeCodePatterns

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

clang_parseTranslationUnit的问题是预编译的报头在第二次称为代码完成时不会重用。计算预编译前导码花费的时间超过 90%,因此您应该允许尽快重用预编译前导码。

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

看看ASTUnit.cpp中的这个变量"PreambleRebuildCounter"。

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

有时,

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

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

如果这没有帮助,您可以分析您的流程以查看它花费了大部分时间。