[cfe-dev] Clang indexing library performance

Alexander Bolodurin alexander.bolodurin at gmail.com
Mon Oct 10 05:51:18 PDT 2011


On 10/10/2011, at 10:56 PM, Tobias Grosser wrote:

> On 10/10/2011 12:50 PM, Alex wrote:
>> 2011/10/3 Tobias Grosser <tobias at grosser.es <mailto:tobias at grosser.es>>
>> 
>> Thanks, I think there are no low-hanging fruit left on Clang's side. If
>> you know of any, feel free to share. :)
>> 
>> I'll probably be writing my own completer in the medium term to replace
>> clang_complete's Python implementation (which now takes 50% of the time
>> trying to complete things like "boost::") in C++. I already
>> tried optimizing Python version, but there is only so much you can do.
> 
> So did you find out where the bottleneck in the clang_complete's python implementation is?

I could get Python implementation from ~600ms overhead to ~160ms with some dirty code (patch attached). CPython does very few optimizations (if any at all), so all the redundant iterations over the list of chunks in a completion string create a lot of temporary objects and make a lot of calls via ctypes. I unrolled all the chunk information from completion strings before doing any transformations.

> 
> My limited investigation has shown that it's just slow with a large number of results. Limiting the results to about 10 gives almost zero overhead.

Yes, it works well on small datasets, but I work with boost and use Supertab, so I often happen to trigger autocompletion, and it often happes to be with boost namespace, which contains half a universe. One way to avoid it would be to stop using Supertab and use C-x C-o, but it's a workaround, not a solution.

> To me it seems the sorting and filtering is very inefficient.
> I did not yet look into how to improve it, but believe there should be some possibilities, e.g. by filtering unneeded results early.

I though about filtering early but it doesn't seem to work because Clang completion is triggered only once, the rest of the filtering is handled by Vim itself as you type. So if you don't have the full list and happen to need boost::weak_ptr, which, being at the bottom of the list of 10,000 items was filtered out, you'd have to re-trigger Clang completion for every keystroke.

I also tried to make a lazy dict for each result object from a completion string, but that wouldn't work as clang_complete has to realize the entire list anyway when marshalling the result into VimScript land.

> 
> As you seem to plan your own implementation. What would you do different to overcome the performance problems you found in the python implementation?
> 
> Cheers
> Tobi
> 

Eliminating Python for filtering and formatting would be a good step, I think? :) One could try to optimize it further, but to me it seems like an exercise in frustration. I didn't yet investigate how much of the time is spent in VimScript, but I think it can be done better than 150ms. Another thing is trying to start indexing in the background maybe, this first parse/reparse step is painfully long. An indexing daemon process with some IPC layer, perhaps?

Regards,
Alex.

PS

Forgot to CC the mailing list the first time around.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: clang_complete_hack.patch
Type: application/octet-stream
Size: 4036 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20111010/07d4dc07/attachment.obj>


More information about the cfe-dev mailing list