ccls icon indicating copy to clipboard operation
ccls copied to clipboard

Comparison with clangd

Open sergei-dyshel opened this issue 2 years ago • 7 comments

As far as I understand there are currently only 2 state-of-the-art LSP servers for C/C++: ccls and clangd. Back then, when cquery development stalled and ccls emerged, it was clearly much more robust than clangd (e.g. had proper whole codebase index) so there was no doubt for one who wanted to choose most functional C/C++ server for his project.

But since then clangd advanced a lot and today is pretty comparable to ccls in terms of functionality and robustness (IMO). I believe the community of C++ users will greatly benefit from having an unbiased comparison between these two great LSP servers. Some examples of areas to compare in:

  • Language features support (standard revision, particular "complex" features of C++ etc)
  • LSP protocol support, also protocol extensions.
  • Differences in editor-specific extensions.
  • Performance difference (parsing in both is done by libclang, but for example index implementations are different).

@MaskRay do you track clangd progress and can share any information on that? Do you see a point in such comparison at all?

PS. Sorry for posting it here, "discussions" page for ccls repo is disabled. Will gladly move this discussion to more appropriate place.

sergei-dyshel avatar Apr 16 '22 19:04 sergei-dyshel

In my experience, ccls is significantly more performant than clangd (tried v13 last) with respect to indexing speed, and that by itself is the greatest reason to prefer it over clangd, and outweighs any other benefits that may be provided by the other. ccls cache organization also seems superior to clangd which either litters the sources directories, or with even the option to store outside seems to have its downsides (I forget the exact details now).

That said, ccls development seems to have relatively stalled in some ways, especially compared to clangd which seems to be actively keeping up with LSP developments. ccls implementation of call hierarchies, and semantic highlighting while work great are not LSP compliant if I'm not mistaken and don't work universally with all LSP client implementations seamlessly for these features (the hierarchy was implemented even before it was adopted by the standard perhaps).

At least at this point, for me to be using ccls I don't feel like I'm missing out on anything that clangd might offer, but perhaps that could change in future.

Much gratitude to @MaskRay for ccls work.

damnskippy avatar Apr 17 '22 15:04 damnskippy

In my experience, ccls is significantly more performant than clangd (tried v13 last) with respect to indexing speed, and that by itself is the greatest reason to prefer it over clangd, and outweighs any other benefits that may be provided by the other.

I agree that indexing speed would be crucial advantage but currently I don't observe it. I configured vscode to run both ccls and clang simultaneously (very nice feature BTW) so that I can visually track both indexers' progress in status line. From what I see, on my moderately big codebase, both servers index it in roughly the same time (both configured with same number of threads). This is not a proper benchmark though, I hope to find time to do proper benchmarking by running each server in offline mode.

ccls cache organization also seems superior to clangd which either litters the sources directories, or with even the option to store outside seems to have its downsides (I forget the exact details now).

Interesting, never experienced this "littering". AFAIK clangd currently stores cache in .cache/clangd, just as ccls stores in .ccls-cache. The format and organization of cache looks different though, I'm wondering if it's possible somehow to compare database speed for more heavy requests, such as references search or call hierarchy.

Much gratitude to @MaskRay for ccls work.

Indeed, ccls (and cquery before it) was huge step forward in making C/C++ development easier. @MaskRay, thank you very much for that!

To continue the topic on comparison, here are two differences I noticed in last couple of days:

  1. ccls displays "docstring" (comment annotating the member) for completion candidates - very useful feature when studying new codebase.
  2. clangd has auto-completion mode where it inserts full function signature with placeholders for arguments. I could find ccls option to do that.

sergei-dyshel avatar Apr 18 '22 18:04 sergei-dyshel

clangd has auto-completion mode where it inserts full function signature with placeholders for arguments. I could find ccls option to do that.

This might depend on your LSP client. I'm using emacs-lsp with ccls and it does this for me (if I'm understanding what you mean: do you mean when you define the function or when you call the function?) I can then tab across to fill in each placeholder.

madscientist avatar Jul 26 '22 21:07 madscientist

clangd still could not support c++20 ranges, in fact clang tools are behind c++ by quite a bit(comparing to gcc), can ccls work well with newest c++ these days comparing to clangd.

laoshaw avatar Aug 02 '22 22:08 laoshaw

I'm by no means an C++ expert, but ranges library is just an addition to standard library C++, there should be no specific support in clangd/ccls for it, it all depends on support of this lib in stdc++/libc++. I'm also curios about what

clang tools are behind c++ by quite a bit

does mean...

sergei-dyshel avatar Aug 03 '22 09:08 sergei-dyshel

yes I added a c++20 flag to clangd and now it works, you're correct.

clang is behind gcc on c++ new features(c++20 etc) is what I meant.

thanks!

laoshaw avatar Aug 03 '22 14:08 laoshaw

If you work on a large code base containing many many thousands of files and are using a cloneable file system such as Linux btrfs, the following workflow results in vastly superior experience when using ccls.

  1. Setup a cronjob that runs at midnight to fetch the lastest sources into say proj_latest, run ccls with --index to index areas that you are working in. In our environment using a 24-core system, this takes hours.
  2. During the day clone proj_latest into proj_workarea. This takes about a second and because you are using a cloneable file system, it's very space efficient. In proj_workarea, you'll have many many thousands of files already indexed and this took typically a second or so.
  3. In your editor, tell ccls to update the paths to the sources using the pathMappings option. You'll have immediate LSP capabilities after the ccls server startup (which can take a few minutes on a large index). No indexing is required!

clangd has no way to pre-generate a movable index. clangd does have a remote index concept, but clangd hardcodes the full paths in its index and provides no path mapping capability. See https://github.com/clangd/clangd/issues/847. Perhaps the reason why this capability doesn't exist in clangd is that it's typically used on smaller code bases or maybe those working on clangd haven't leveraged cloneable file systems?

JohnC32 avatar May 03 '23 19:05 JohnC32