From 0e70bf098f14ccfe4c598b89fceb240be10d9496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Istv=C3=A1n=20So=C3=B3s?= Date: Mon, 11 Nov 2024 16:19:51 +0100 Subject: [PATCH] Reduce Score creation in the search ranking step. (#8264) --- app/lib/search/mem_index.dart | 42 ++++++++++++++++----------------- app/lib/search/token_index.dart | 8 +++++-- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/app/lib/search/mem_index.dart b/app/lib/search/mem_index.dart index e8a199309..95271a31a 100644 --- a/app/lib/search/mem_index.dart +++ b/app/lib/search/mem_index.dart @@ -30,7 +30,7 @@ class InMemoryPackageIndex { /// Adjusted score takes the overall score and transforms /// it linearly into the [0.4-1.0] range. - final _adjustedOverallScores = {}; + late final List _adjustedOverallScores; late final List _overallOrderedHits; late final List _createdOrderedHits; late final List _updatedOrderedHits; @@ -197,13 +197,11 @@ class InMemoryPackageIndex { /// Adjusted score takes the overall score and transforms /// it linearly into the [0.4-1.0] range, to allow better /// multiplication outcomes. - final overallScore = textResults.pkgScore - .mapValues((key, value) => value * _adjustedOverallScores[key]!); - packageHits = _rankWithValues(overallScore); + packageScores.multiplyAllFromValues(_adjustedOverallScores); + packageHits = _rankWithValues(packageScores); break; case SearchOrder.text: - final score = textResults?.pkgScore ?? Score.empty; - packageHits = _rankWithValues(score); + packageHits = _rankWithValues(packageScores); break; case SearchOrder.created: packageHits = _createdOrderedHits.whereInScores(packageScores); @@ -251,7 +249,7 @@ class InMemoryPackageIndex { /// Update the overall score both on [PackageDocument] and in the [_adjustedOverallScores] map. void _updateOverallScores() { - for (final doc in _documentsByName.values) { + _adjustedOverallScores = _documents.map((doc) { final downloadScore = doc.popularityScore ?? 0.0; final likeScore = doc.likeScore ?? 0.0; final popularity = (downloadScore + likeScore) / 2; @@ -259,8 +257,8 @@ class InMemoryPackageIndex { final overall = popularity * 0.5 + points * 0.5; doc.overallScore = overall; // adding a base score prevents later multiplication with zero - _adjustedOverallScores[doc.package] = 0.4 + 0.6 * overall; - } + return 0.4 + 0.6 * overall; + }).toList(); } _TextResults? _searchText( @@ -272,6 +270,9 @@ class InMemoryPackageIndex { if (text != null && text.isNotEmpty) { final words = splitForQuery(text); if (words.isEmpty) { + for (var i = 0; i < packageScores.length; i++) { + packageScores.setValue(i, 0); + } return _TextResults.empty(); } @@ -361,7 +362,6 @@ class InMemoryPackageIndex { } return _TextResults( - packageScores.toScore(), topApiPages, nameMatches: nameMatches?.toList(), ); @@ -369,18 +369,21 @@ class InMemoryPackageIndex { return null; } - List _rankWithValues(Map values) { - final list = values.entries - .map((e) => PackageHit(package: e.key, score: e.value)) - .toList(); + List _rankWithValues(IndexedScore score) { + final list = []; + for (var i = 0; i < score.length; i++) { + final value = score.getValue(i); + if (value <= 0.0) continue; + list.add(IndexedPackageHit( + i, PackageHit(package: score.keys[i], score: value))); + } list.sort((a, b) { - final int scoreCompare = -a.score!.compareTo(b.score!); + final scoreCompare = -a.hit.score!.compareTo(b.hit.score!); if (scoreCompare != 0) return scoreCompare; // if two packages got the same score, order by last updated - return _compareUpdated( - _documentsByName[a.package]!, _documentsByName[b.package]!); + return _compareUpdated(_documents[a.index], _documents[b.index]); }); - return list; + return list.map((h) => h.hit).toList(); } List _rankWithComparator( @@ -438,18 +441,15 @@ class InMemoryPackageIndex { } class _TextResults { - final Score pkgScore; final Map>> topApiPages; final List? nameMatches; factory _TextResults.empty() => _TextResults( - Score.empty, {}, nameMatches: null, ); _TextResults( - this.pkgScore, this.topApiPages, { required this.nameMatches, }); diff --git a/app/lib/search/token_index.dart b/app/lib/search/token_index.dart index e2f51af87..99dcabda1 100644 --- a/app/lib/search/token_index.dart +++ b/app/lib/search/token_index.dart @@ -297,10 +297,14 @@ class IndexedScore { } void multiplyAllFrom(IndexedScore other) { - assert(other._values.length == _values.length); + multiplyAllFromValues(other._values); + } + + void multiplyAllFromValues(List values) { + assert(_values.length == values.length); for (var i = 0; i < _values.length; i++) { if (_values[i] == 0.0) continue; - final v = other._values[i]; + final v = values[i]; _values[i] = v == 0.0 ? 0.0 : _values[i] * v; } }