J'étudie les accélérations potentielles de complétion de code tout en utilisant le mécanisme de complétion de code de clang. Le flux décrit ci-dessous est ce que j'ai trouvé dans rtags , par Anders Bakken.
Les unités de traduction sont analysées par un démon surveillant les fichiers pour les changements. Ceci est fait par clang_parseTranslationUnit
les fonctions appelées et associées ( reparse*
, dispose*
). Lorsque l'utilisateur demande une complétion à une ligne et une colonne données dans un fichier source, le démon transmet l'unité de traduction mise en cache pour la dernière version enregistrée du fichier source et le fichier source actuel à clang_codeCompleteAt
. ( Clang CodeComplete docs ).
Les indicateurs passés à clang_parseTranslationUnit
(de CompletionThread :: process, ligne 271 ) sont CXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_CacheCompletionResults|CXTranslationUnit_SkipFunctionBodes
. Les indicateurs passés à clang_codeCompleteAt
(de CompletionThread :: process, ligne 305 ) sont CXCodeComplete_IncludeMacros|CXCodeComplete_IncludeCodePatterns
.
L'appel à clang_codeCompleteAt
est très lent - il faut environ 3 à 5 secondes pour obtenir un achèvement, même dans les cas où l'emplacement d'achèvement est un code d'accès membre légitime, un sous-ensemble du cas d'utilisation prévu mentionné dans la documentation de clang_codeCompleteAt
. Cela semble bien trop lent par rapport aux normes de complétion de code IDE. Y a-t-il un moyen d'accélérer cela?
CXTranslationUnit_SkipFunctionBodies
,CXCodeComplete_IncludeMacros
,CXCodeComplete_IncludeCodePatterns
et ne voit pas de différence significative sur la base de code , je travaille avec. Tous en moyenne environ 4 secondes par complet. Je suppose que c'est juste à cause de la taille des UT.CXTranslationUnit_PrecompiledPreamble
assurereparseTU
est très rapide. Cependant, même avecCXTranslationUnit_CacheCompletionResults
,clang_codeCompleteAt
c'est douloureusement lent pour mon cas d'utilisation.Réponses:
Le problème de clang_parseTranslationUnit est que le préambule précompilé n'est pas réutilisé la deuxième fois que l'on appelle l'achèvement du code. Le calcul du préambule précompilé prend plus de 90% de ce temps, vous devez donc permettre que le préambule précompilé soit réutilisé dès que possible.
Par défaut, il est réutilisé la troisième fois qu'il est appelé pour analyser / analyser l'unité de traduction.
Jetez un œil à cette variable «PreambleRebuildCounter» dans ASTUnit.cpp.
Un autre problème est que ce préambule est enregistré dans un fichier temporaire. Vous pouvez conserver le préambule précompilé en mémoire au lieu d'un fichier temporaire. Ce serait plus rapide. :)
la source
Parfois, des retards de cette ampleur sont dus à des délais d'expiration sur les ressources réseau (partages NFS ou CIFS sur un chemin de recherche de fichier ou des sockets). Essayez de surveiller le temps nécessaire à chaque appel système en préfixant le processus avec lequel vous exécutez
strace -Tf -o trace.out
. Regardez les nombres entre crochetstrace.out
pour l'appel système qui prend beaucoup de temps.Vous pouvez également surveiller le temps entre les appels système pour voir quel traitement d'un fichier prend trop de temps. Pour ce faire, préfixez le processus avec lequel vous exécutez
strace -rf -o trace.out
. Regardez le numéro avant chaque appel système pour rechercher de longs intervalles d'appels système. Revenez en arrière à partir de ce point à la recherche d'open
appels pour voir quel fichier était en cours de traitement.Si cela ne vous aide pas, vous pouvez profiler votre processus pour voir où il passe la plupart de son temps.
la source