diff --git a/bundles/org.eclipse.search/newsearch/org/eclipse/search/ui/text/AbstractTextSearchResult.java b/bundles/org.eclipse.search/newsearch/org/eclipse/search/ui/text/AbstractTextSearchResult.java
index bd9ec3711b6..bffdd573fd6 100644
--- a/bundles/org.eclipse.search/newsearch/org/eclipse/search/ui/text/AbstractTextSearchResult.java
+++ b/bundles/org.eclipse.search/newsearch/org/eclipse/search/ui/text/AbstractTextSearchResult.java
@@ -44,6 +44,7 @@ public abstract class AbstractTextSearchResult implements ISearchResult {
 	private final ConcurrentMap<Object, Set<Match>> fElementsToMatches;
 	private final List<ISearchResultListener> fListeners;
 	private final MatchEvent fMatchEvent;
+	private volatile int matchCount;
 
 	private MatchFilter[] fMatchFilters;
 
@@ -157,6 +158,7 @@ private MatchEvent getSearchResultEvent(Collection<Match> matches, int eventKind
 
 	private boolean didAddMatch(Match match) {
 		updateFilterState(match);
+		matchCount = -1;
 		return fElementsToMatches.computeIfAbsent(match.getElement(), k -> ConcurrentHashMap.newKeySet()).add(match);
 	}
 
@@ -178,6 +180,7 @@ public void removeAll() {
 		fireChange(new RemoveAllEvent(this));
 	}
 	private void doRemoveAll() {
+		matchCount = 0;
 		fElementsToMatches.clear();
 	}
 
@@ -216,6 +219,7 @@ public void removeMatches(Match[] matches) {
 
 	private boolean didRemoveMatch(Match match) {
 		boolean[] existed = new boolean[1];
+		matchCount = -1;
 		fElementsToMatches.computeIfPresent(match.getElement(), (f, matches) -> {
 			existed[0] = matches.remove(match);
 			if (matches.isEmpty()) {
@@ -302,10 +306,14 @@ private boolean updateFilterState(Match match) {
 	 * @return total number of matches
 	 */
 	public int getMatchCount() {
-		int count = 0;
+		int count = matchCount;
+		if (count != -1) {
+			return count;
+		}
 		for (Set<Match> element : fElementsToMatches.values()) {
 			count += element.size();
 		}
+		matchCount = count;
 		return count;
 	}