diff --git a/clang-tools-extra/clangd/index/dex/Iterator.cpp b/clang-tools-extra/clangd/index/dex/Iterator.cpp --- a/clang-tools-extra/clangd/index/dex/Iterator.cpp +++ b/clang-tools-extra/clangd/index/dex/Iterator.cpp @@ -104,11 +104,19 @@ // In this case, just terminate the process. if (ReachedEnd) return; + // Cache the result so that peek() is not called again as it may be + // quite expensive in AND with large subtrees. + auto Candidate = Child->peek(); // If any child goes beyond given ID (i.e. ID is not the common item), // all children should be advanced to the next common item. - if (Child->peek() > SyncID) { - SyncID = Child->peek(); + if (Candidate > SyncID) { + SyncID = Candidate; NeedsAdvance = true; + // Reset and try to sync again. Sync starts with the first child as + // this is the cheapest (smallest size estimate). This way advanceTo + // is called on the large posting lists once the sync point is very + // likely. + break; } } } while (NeedsAdvance);