Estoy investigando posibles aceleraciones de finalización de código mientras uso el mecanismo de finalización de código de clang. El flujo que se describe a continuación es lo que encontré en rtags , de Anders Bakken.
Las unidades de traducción se analizan mediante un demonio que supervisa los archivos en busca de cambios. Esto se realiza mediante clang_parseTranslationUnit
funciones llamadas y relacionadas ( reparse*
, dispose*
). Cuando el usuario solicita que se complete una línea y columna determinadas en un archivo de origen, el demonio pasa la unidad de traducción en caché para la última versión guardada del archivo de origen y el archivo de origen actual a clang_codeCompleteAt
. ( Documentos Clang CodeComplete ).
Las banderas pasadas a clang_parseTranslationUnit
(de CompletionThread :: process, línea 271 ) son CXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_CacheCompletionResults|CXTranslationUnit_SkipFunctionBodes
. Las banderas pasadas a clang_codeCompleteAt
(de CompletionThread :: process, línea 305 ) son CXCodeComplete_IncludeMacros|CXCodeComplete_IncludeCodePatterns
.
La llamada a clang_codeCompleteAt
es muy lenta: toma alrededor de 3-5 segundos obtener una finalización incluso en los casos en que la ubicación de finalización es un código de acceso de miembro legítimo, un subconjunto del caso de uso previsto mencionado en la documentación de clang_codeCompleteAt
. Esto parece demasiado lento para los estándares de finalización de código IDE. ¿Hay alguna forma de acelerar esto?
CXTranslationUnit_SkipFunctionBodies
,CXCodeComplete_IncludeMacros
,CXCodeComplete_IncludeCodePatterns
y no ver una diferencia significativa en la base de código que estoy trabajando con. Todos ellos promedian alrededor de 4 segundos por completo. Supongo que esto se debe solo al tamaño de las unidades de traducción.CXTranslationUnit_PrecompiledPreamble
asegurareparseTU
es muy rápido. Sin embargo, incluso conCXTranslationUnit_CacheCompletionResults
,clang_codeCompleteAt
es dolorosamente lento para mi caso de uso.Respuestas:
El problema que tiene clang_parseTranslationUnit es que el preámbulo precompilado no se reutiliza la segunda vez que se llama finalización de código. Calcular el preámbulo precompilado toma más del 90% de este tiempo, por lo que debe permitir que el preámbulo precompilado se reutilice lo antes posible.
De forma predeterminada, se reutiliza la tercera vez que se llama para analizar / analizar la unidad de traducción.
Eche un vistazo a esta variable 'PreambleRebuildCounter' en ASTUnit.cpp.
Otro problema es que este preámbulo se guarda en un archivo temporal. Puede mantener el preámbulo precompilado en la memoria en lugar de un archivo temporal. Sería más rápido. :)
fuente
A veces, los retrasos de esta magnitud se deben a tiempos de espera en los recursos de red (recursos compartidos de NFS o CIFS en una ruta de búsqueda de archivos o sockets). Intente monitorear el tiempo que cada llamada al sistema tarda en completarse prefijando el proceso con el que se ejecuta
strace -Tf -o trace.out
. Mire los números entre paréntesis angularestrace.out
para la llamada al sistema que tarda mucho en completarse.También puede monitorear el tiempo entre llamadas al sistema para ver qué procesamiento de un archivo tarda demasiado en completarse. Para hacer esto, prefija el proceso con el que se ejecuta
strace -rf -o trace.out
. Mire el número antes de cada llamada al sistema para buscar intervalos largos de llamadas al sistema. Vaya hacia atrás desde ese punto buscandoopen
llamadas para ver cuál era el archivo que se estaba procesando.Si esto no ayuda, puede crear un perfil de su proceso para ver dónde pasa la mayor parte del tiempo.
fuente