Швидше заповнення коду клангом


108

Я досліджую потенційні скорочення заповнення коду, використовуючи механізм заповнення коду Кланг. Нижче описаний потік - це те, що я знайшов у rtags від Anders Bakken.

Одиниці перекладу аналізуються файлами моніторингу демонів щодо змін. Це робиться за допомогою викликаних clang_parseTranslationUnitта пов'язаних з ними функцій ( reparse*, dispose*). Коли користувач вимагає заповнити заданий рядок і стовпець у вихідному файлі, демон передає кешований блок перекладу для останньої збереженої версії вихідного файлу та поточного вихідного файла clang_codeCompleteAt. ( Документи Clang CodeComplete ).

Прапори, передані clang_parseTranslationUnit(від CompletionThread :: process, рядок 271 ) є CXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_CacheCompletionResults|CXTranslationUnit_SkipFunctionBodes. Прапори, передані clang_codeCompleteAt(від CompletionThread :: process, рядок 305 ) є CXCodeComplete_IncludeMacros|CXCodeComplete_IncludeCodePatterns.

Виклик на clang_codeCompleteAtдуже повільний - потрібно близько 3-5 секунд, щоб отримати завершення навіть у тих випадках, коли місце завершення є законним кодом доступу учасника, підмножиною випадку передбачуваного використання, зазначеного в документації clang_codeCompleteAt. Це здається занадто повільним стандартами заповнення коду IDE. Чи є спосіб прискорити це?


8
Я б радий допомогти вам, але нам потрібно більше деталей. Приклад коду було б добре для початку
raph.amiard

1
Пінг. Чи є прогрес у цій проблемі?
Mehrwolf

4
@Cameron Вибачте за довгу затримку повернення до вас. Я спробував все 8 комбінацій CXTranslationUnit_SkipFunctionBodies, CXCodeComplete_IncludeMacros, CXCodeComplete_IncludeCodePatternsі не бачу суттєву різницю на кодовому я працюю с. Усі вони в середньому становлять близько 4 секунд на повну. Я здогадуюсь це тільки через розмір TU. CXTranslationUnit_PrecompiledPreambleзабезпечує reparseTUдуже швидко. Тим НЕ менше, навіть з CXTranslationUnit_CacheCompletionResults, clang_codeCompleteAtболісно повільно для мого сценарію використання.
Прадхан

1
@Mehrwolf Ack. Дивіться коментар вище.
Прадхан

7
Гм, це прикро. Чи можете ви відтворити повільність завершення роботи на підрозділі перекладу, доступному для громадськості (наприклад, з відкритим кодом)? Це допомогло б, якби ми змогли самі це відтворити. Завершення повинно бути приблизно таким же швидким, як і повторний аналіз, оскільки це робиться всередині (він вводить спеціальний маркер заповнення коду і аналізує до цього моменту).
Камерон

Відповіді:


6

Проблема, яку має clang_parseTranslationUnit, полягає в тому, що попередньо складена преамбула не використовується повторно, що називається завершенням коду. Підрахунок преамбули прекомпіляції займає більше 90% цього часу, тому ви повинні дозволити, що попередньо складена преамбула була використана якнайшвидше.

За замовчуванням він використовується повторно в третій раз, який викликається для розбору / повторного аналізу трансляції.

Подивіться цю змінну "PreambleRebuildCounter" в ASTUnit.cpp.

Інша проблема полягає в тому, що ця преамбула зберігається у тимчасовому файлі. Ви можете зберігати попередньо складену преамбулу в пам'яті замість тимчасового файлу. Це було б швидше. :)


Дивовижно! Це звучить так, як потрапляє до справжнього питання. Поглянемо на це і дамо вам знати. Дякую!
Прадхан

гаразд! дайте мені знати, чи працює це для вас! і якщо у вас є якісь питання, не соромтесь запитати мене !!!!
GutiMac

4

Іноді затримки такої величини пов'язані із затримкою часу на мережевих ресурсах (NFS або CIFS-спільноти на шляху пошуку файлів або сокетів). Спробуйте відстежувати час завершення кожного системного дзвінка, встановивши префікс процесу, з якого ви запустите strace -Tf -o trace.out. Подивіться цифри в кутових дужках trace.outдля системного дзвінка, який потребує тривалого часу.

Ви також можете відстежувати час між системними дзвінками, щоб побачити, яка обробка файлу займає занадто багато часу, щоб завершити. Для цього слід встановити префікс процесу, з яким ви запустите strace -rf -o trace.out. Подивіться на номер перед кожним системним викликом, щоб шукати довгі інтервали системного виклику. Поверніться назад із цього пункту, шукаючи openдзвінки, щоб побачити, який файл оброблявся.

Якщо це не допомагає, ви можете профайлювати процес, щоб побачити, де він проводить більшу частину свого часу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.