C++ 使用叮当声更快地完成代码

C++ 使用叮当声更快地完成代码,c++,clang,llvm,code-completion,libclang,C++,Clang,Llvm,Code Completion,Libclang,我正在调查使用clang的代码完成机制时潜在的代码完成加速。下面描述的流程是我在Anders Bakken的文章中发现的 翻译单元由监控文件更改的守护进程解析。这是通过调用clang\u parseTranslationUnit和相关函数(repasse*,dispose*)完成的。当用户在源文件中的给定行和列请求完成时,守护进程会将源文件上次保存版本和当前源文件的缓存翻译单元传递给clangu codeCompleteAt。() 传递到clang_parseTranslationUnit(fr

我正在调查使用clang的代码完成机制时潜在的代码完成加速。下面描述的流程是我在Anders Bakken的文章中发现的

翻译单元由监控文件更改的守护进程解析。这是通过调用
clang\u parseTranslationUnit
和相关函数(
repasse*
dispose*
)完成的。当用户在源文件中的给定行和列请求完成时,守护进程会将源文件上次保存版本和当前源文件的缓存翻译单元传递给
clangu codeCompleteAt
。()

传递到
clang_parseTranslationUnit
(from)的标志是
cxtranlationUnit_预编译序言| cxtranlationUnit_缓存完成结果| cxtranlationUnit_SkipFunctionBodes
。传递给
clang\u codecomplete
(from)的标志是
CXCodeComplete\u includegrams\CXCodeComplete\u IncludeCodePatterns


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

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

您还可以监视系统调用之间的时间间隔,以查看哪些文件处理花费的时间太长而无法完成。为此,请使用
strace-rf-o trace.out
作为运行进程的前缀。查看每次系统调用之前的号码,以查找较长的系统调用间隔。从那一点开始向后看
open
调用,看看哪个文件正在被处理


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

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

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

查看ASTUnit.cpp中的变量“PreambleBuildCounter”


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

我很乐意帮助你,但我们需要更多的细节。示例代码将有助于启动。这个问题有进展吗?@Cameron很抱歉耽误了这么长时间才回复你。我尝试了
cxtransationunit\u skipfunctionbody
CXCodeComplete\u IncludeMacros
CXCodeComplete\u IncludeCodePatterns
的所有8种组合,没有发现我正在使用的代码库有显著差异。所有这些测试平均每完成4秒左右。我想这只是因为土族的大小
CXTranslationUnit\u预编译前导码
确保了
Repassetu
的速度非常快。然而,即使使用
cxtransationunit\u CacheCompletionResults
clang\u codeCompleteAt
对于我的用例来说速度也非常慢。@Mehrwolf Ack。看上面的评论。嗯,那很不幸。你能在一个可供公众使用的翻译单元上重现完成慢度吗(例如开源)?如果我们能够自己复制这一点,这将有所帮助。完成的速度应该大致与重新分析的速度一样快,因为这是它内部所做的(它注入了一个特殊的代码完成标记,并解析到该点)。太棒了!这听起来像是真正的问题。我会看看这个,然后告诉你。谢谢好啊让我知道它是否适合你!如果你有任何问题,请随时问我!!!!