Clang ile daha hızlı kod tamamlama


108

Clang'ın kod tamamlama mekanizmasını kullanırken olası kod tamamlama hızlandırmalarını araştırıyorum. Aşağıda açıklanan akış , Anders Bakken tarafından yazılan rtag'lerde bulduğum şeydir .

Çeviri birimleri, değişiklikler için dosyaları izleyen bir arka plan programı tarafından ayrıştırılır. Bu, çağrılan clang_parseTranslationUnitve ilgili işlevler ( reparse*, dispose*) tarafından yapılır . Kullanıcı bir kaynak dosyadaki belirli bir satır ve sütunda bir tamamlama istediğinde, arka plan programı kaynak dosyanın son kaydedilen sürümü için önbelleğe alınmış çeviri birimini ve geçerli kaynak dosyasını clang_codeCompleteAt. ( Clang CodeComplete belgeleri ).

clang_parseTranslationUnit( CompletionThread :: process, satır 271'den ) iletilen bayraklar CXTranslationUnit_PrecompiledPreamble|CXTranslationUnit_CacheCompletionResults|CXTranslationUnit_SkipFunctionBodes. clang_codeCompleteAt( CompletionThread :: process, satır 305'ten ) 'e aktarılan bayraklar CXCodeComplete_IncludeMacros|CXCodeComplete_IncludeCodePatterns.

Çağrı clang_codeCompleteAtçok yavaştır - tamamlanma yerinin, belgelerinde belirtilen kullanım amacının bir alt kümesi olan meşru üye erişim kodu olduğu durumlarda bile tamamlanması yaklaşık 3-5 saniye sürer clang_codeCompleteAt. IDE kod tamamlama standartlarına göre bu çok yavaş görünüyor. Bunu hızlandırmanın bir yolu var mı?


8
Size yardımcı olmaktan memnuniyet duyarım ama daha fazla ayrıntıya ihtiyacımız var. Örnek kod bir başlangıç ​​için iyi olabilir
raph.amiard

1
Ping. Bu problemde herhangi bir ilerleme var mı?
Mehrwolf

4
@Cameron Size geri dönmedeki uzun gecikme için özür dilerim. Ben her 8 kombinasyonları denedi CXTranslationUnit_SkipFunctionBodies, CXCodeComplete_IncludeMacros, CXCodeComplete_IncludeCodePatternsve ben ile çalışıyorum kodu tabanında önemli bir fark görmedik. Hepsi tamamlanma başına ortalama 4 saniyedir. Sanırım bu sadece TU'ların boyutu yüzünden. CXTranslationUnit_PrecompiledPreambleolmasını sağlar reparseTUçok hızlı. Ancak, hatta ile CXTranslationUnit_CacheCompletionResults, clang_codeCompleteAtacı benim bir kullanım örneği için yavaşlayabilir.
Pradhan

1
@Mehrwolf Ack. Yukarıdaki yoruma bakın.
Pradhan

7
Hmm, bu talihsiz bir durum. Halka açık bir çeviri biriminde (örneğin açık kaynak) tamamlama yavaşlığını yeniden üretebilir misiniz? Bunu kendimiz yeniden üretebilseydik yardımcı olurduk. Tamamlama, kabaca yeniden ayrıştırma kadar hızlı olmalıdır, çünkü dahili olarak yaptığı şey budur (özel bir kod tamamlama belirteci enjekte eder ve o noktaya kadar ayrıştırır).
Cameron

Yanıtlar:


6

Clang_parseTranslationUnit'in sahip olduğu sorun, önceden derlenmiş önsözün kod tamamlama olarak adlandırılan ikinci kez yeniden kullanılmamasıdır. Ön derleme önsözünün hesaplanması bu sürenin% 90'ından fazlasını alır, bu nedenle önceden derlenmiş önsözün mümkün olan en kısa sürede yeniden kullanılmasına izin vermelisiniz.

Varsayılan olarak, çeviri birimini ayrıştırmak / yeniden ayrıştırmak için çağrılan üçüncü kez yeniden kullanılır.

ASTUnit.cpp'de bu değişken 'PreambleRebuildCounter'a bir göz atın.

Diğer bir sorun da bu önsözün geçici bir dosyaya kaydedilmiş olmasıdır. Önceden derlenmiş ön eki geçici bir dosya yerine bellekte tutabilirsiniz. Daha hızlı olur. :)


Müthiş! Bu gerçek konuya giriyor gibi görünüyor. Buna bir göz atacak ve size haber vereceğim. Teşekkürler!
Pradhan

tamam! sizin için işe yarayıp yaramadığını bana bildirin! ve herhangi bir sorunuz varsa bana sormaktan çekinmeyin !!!!
GutiMac

4

Bazen bu büyüklükteki gecikmeler, ağ kaynaklarındaki (bir dosya arama yolundaki veya soketlerdeki NFS veya CIFS paylaşımları) zaman aşımlarından kaynaklanır. Çalıştırdığınız işlemin önüne ekleyerek her sistem çağrısının tamamlanması için gereken süreyi izlemeyi deneyin strace -Tf -o trace.out. trace.outTamamlanması uzun süren sistem çağrısı için köşeli parantez içindeki sayılara bakın .

Ayrıca , bir dosyanın hangi işlemesinin tamamlanmasının çok uzun sürdüğünü görmek için sistem çağrıları arasındaki süreyi de izleyebilirsiniz . Bunu yapmak için çalıştırdığınız sürecin önüne ekleyin strace -rf -o trace.out. Uzun sistem çağrı aralıklarını aramak için her sistem çağrısından önce numaraya bakın. İşlenmekte openolan dosyanın hangisi olduğunu görmek için çağrıları ararken o noktadan geriye gidin .

Bu işe yaramazsa, zamanının çoğunu nerede geçirdiğini görmek için sürecinizin profilini çıkarabilirsiniz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.