From b87b023db0a7fcd2fdc92916dd572afe8926040c Mon Sep 17 00:00:00 2001 From: Igor Kushnir Date: Sun, 22 May 2022 22:21:00 +0300 Subject: [PATCH] Optimize highlighting FTS matches in articles The wall time of calls to ArticleView::highlightAllFtsOccurences() on my GNU/Linux system before and at this commit: allMatches.size() uniqueMatches.size() before(ms) at(ms) 79 1 277 4 98 1 380 4 267 1 16803 65 --- articleview.cc | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/articleview.cc b/articleview.cc index 2e01b7f06..8de8efff2 100644 --- a/articleview.cc +++ b/articleview.cc @@ -2664,8 +2664,22 @@ void ArticleView::highlightFTSResults() void ArticleView::highlightAllFtsOccurences( QWebPage::FindFlags flags ) { flags |= QWebPage::HighlightAllOccurrences; - for( int x = 0; x < allMatches.size(); x++ ) - ui.definition->findText( allMatches.at( x ), flags ); + + // Usually allMatches contains mostly duplicates. Thus searching for each element of + // allMatches to highlight them takes a long time => collect unique elements into a + // set and search for them instead. + // Don't use QList::toSet() or QSet's range constructor because they reserve space + // for QList::size() elements, whereas the final QSet size is likely 1 or 2. + QSet< QString > uniqueMatches; + for( int x = 0; x < allMatches.size(); ++x ) + { + QString const & match = allMatches.at( x ); + // Consider words that differ only in case equal if the search is case-insensitive. + uniqueMatches.insert( ftsSearchMatchCase ? match : match.toLower() ); + } + + for( QSet< QString >::const_iterator it = uniqueMatches.constBegin(); it != uniqueMatches.constEnd(); ++it ) + ui.definition->findText( *it, flags ); } void ArticleView::performFtsFindOperation( bool backwards )