Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2008)

Unified Diff: chrome/browser/ui/app_list/search/app_search_provider.cc

Issue 2701123002: AppList Performance Optimization 2 (Closed)
Patch Set: Cache the tokenized name Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/app_list/search/app_search_provider.cc
diff --git a/chrome/browser/ui/app_list/search/app_search_provider.cc b/chrome/browser/ui/app_list/search/app_search_provider.cc
index 9f0642c82ee9ac4ed111e002f1b09c46b47c2d7b..6e8066094315a62df81d79a3496a8c5772cab74b 100644
--- a/chrome/browser/ui/app_list/search/app_search_provider.cc
+++ b/chrome/browser/ui/app_list/search/app_search_provider.cc
@@ -44,7 +44,11 @@ using extensions::ExtensionRegistry;
namespace {
// The size of each step unlaunched apps should increase their relevance by.
-const double kUnlaunchedAppRelevanceStepSize = 0.0001;
+constexpr double kUnlaunchedAppRelevanceStepSize = 0.0001;
+
+// The minimum capacity we reserve in the Apps container which will be filled
+// with extensions and ARC apps, to avoid successive reallocation.
+constexpr size_t kMinimumReservedAppsContainerCapacity = 60U;
}
namespace app_list {
@@ -58,21 +62,31 @@ class AppSearchProvider::App {
const base::Time& install_time)
: data_source_(data_source),
id_(id),
- indexed_name_(base::UTF8ToUTF16(name)),
+ name_(base::UTF8ToUTF16(name)),
last_launch_time_(last_launch_time),
install_time_(install_time) {}
~App() {}
+ TokenizedString* GetTokenizedIndexedName() {
+ // Tokenizing a string is expensive. Don't pay the price for it at
+ // construction of every App, but rather, only when needed (i.e. when the
+ // query is not empty and cache the result.
+ if (!tokenized_indexed_name_)
+ tokenized_indexed_name_ = base::MakeUnique<TokenizedString>(name_);
+ return tokenized_indexed_name_.get();
+ }
+
AppSearchProvider::DataSource* data_source() { return data_source_; }
const std::string& id() const { return id_; }
- const TokenizedString& indexed_name() const { return indexed_name_; }
+ const base::string16& name() const { return name_; }
const base::Time& last_launch_time() const { return last_launch_time_; }
const base::Time& install_time() const { return install_time_; }
private:
AppSearchProvider::DataSource* data_source_;
+ std::unique_ptr<TokenizedString> tokenized_indexed_name_;
const std::string id_;
- const TokenizedString indexed_name_;
+ const base::string16 name_;
const base::Time last_launch_time_;
const base::Time install_time_;
@@ -131,8 +145,8 @@ class ExtensionDataSource : public AppSearchProvider::DataSource,
AppListControllerDelegate* list_controller,
AppListItemList* top_level_item_list,
bool is_recommended) override {
- return std::unique_ptr<AppResult>(new ExtensionAppResult(
- profile(), app_id, list_controller, is_recommended));
+ return base::MakeUnique<ExtensionAppResult>(
+ profile(), app_id, list_controller, is_recommended);
}
// extensions::ExtensionRegistryObserver overrides:
@@ -165,11 +179,10 @@ class ExtensionDataSource : public AppSearchProvider::DataSource,
continue;
}
- std::unique_ptr<AppSearchProvider::App> app(new AppSearchProvider::App(
+ apps->emplace_back(base::MakeUnique<AppSearchProvider::App>(
this, extension->id(), extension->short_name(),
prefs->GetLastLaunchTime(extension->id()),
prefs->GetInstallTime(extension->id())));
- apps->push_back(std::move(app));
}
}
@@ -210,10 +223,9 @@ class ArcDataSource : public AppSearchProvider::DataSource,
if (!app_info->launchable || !app_info->showInLauncher)
continue;
- std::unique_ptr<AppSearchProvider::App> app(new AppSearchProvider::App(
+ apps->emplace_back(base::MakeUnique<AppSearchProvider::App>(
this, app_id, app_info->name, app_info->last_launch_time,
app_info->install_time));
- apps->push_back(std::move(app));
}
}
@@ -222,8 +234,8 @@ class ArcDataSource : public AppSearchProvider::DataSource,
AppListControllerDelegate* list_controller,
AppListItemList* top_level_item_list,
bool is_recommended) override {
- return std::unique_ptr<AppResult>(
- new ArcAppResult(profile(), app_id, list_controller, is_recommended));
+ return base::MakeUnique<ArcAppResult>(profile(), app_id, list_controller,
+ is_recommended);
}
// ArcAppListPrefs::Observer overrides:
@@ -256,16 +268,12 @@ AppSearchProvider::AppSearchProvider(Profile* profile,
top_level_item_list_(top_level_item_list),
clock_(std::move(clock)),
update_results_factory_(this) {
- data_sources_.push_back(
- std::unique_ptr<DataSource>(new ExtensionDataSource(profile, this)));
+ data_sources_.emplace_back(
+ base::MakeUnique<ExtensionDataSource>(profile, this));
#if defined(OS_CHROMEOS)
- if (arc::IsArcAllowedForProfile(profile)) {
- data_sources_.push_back(
- std::unique_ptr<DataSource>(new ArcDataSource(profile, this)));
- }
+ if (arc::IsArcAllowedForProfile(profile))
+ data_sources_.emplace_back(base::MakeUnique<ArcDataSource>(profile, this));
#endif
-
- RefreshApps();
}
AppSearchProvider::~AppSearchProvider() {}
@@ -273,12 +281,10 @@ AppSearchProvider::~AppSearchProvider() {}
void AppSearchProvider::Start(bool /*is_voice_query*/,
const base::string16& query) {
query_ = query;
- ClearResults();
-
- bool show_recommendations = query.empty();
+ const bool show_recommendations = query.empty();
// Refresh list of apps to ensure we have the latest launch time information.
// This will also cause the results to update.
- if (show_recommendations)
+ if (show_recommendations || apps_.empty())
RefreshApps();
UpdateResults();
@@ -289,27 +295,29 @@ void AppSearchProvider::Stop() {
void AppSearchProvider::RefreshApps() {
apps_.clear();
- for (auto& data_source : data_sources_) {
+ apps_.reserve(kMinimumReservedAppsContainerCapacity);
+ for (auto& data_source : data_sources_)
data_source->AddApps(&apps_);
- }
}
void AppSearchProvider::UpdateResults() {
- const TokenizedString query_terms(query_);
- bool show_recommendations = query_.empty();
- ClearResults();
+ const bool show_recommendations = query_.empty();
+ // No need to clear the current results as we will swap them with
+ // |new_results| at the end.
+ SearchProvider::Results new_results;
+ const size_t apps_size = apps_.size();
+ new_results.reserve(apps_size);
if (show_recommendations) {
// Build a map of app ids to their position in the app list.
std::map<std::string, size_t> id_to_app_list_index;
- for (size_t i = 0; i < top_level_item_list_->item_count(); ++i) {
+ for (size_t i = 0; i < top_level_item_list_->item_count(); ++i)
id_to_app_list_index[top_level_item_list_->item_at(i)->id()] = i;
- }
for (auto& app : apps_) {
std::unique_ptr<AppResult> result = app->data_source()->CreateResult(
app->id(), list_controller_, top_level_item_list_, true);
- result->set_title(app->indexed_name().text());
+ result->set_title(app->name());
// Use the app list order to tiebreak apps that have never been launched.
// The apps that have been installed or launched recently should be
@@ -318,34 +326,37 @@ void AppSearchProvider::UpdateResults() {
? app->install_time()
: app->last_launch_time();
if (time.is_null()) {
- auto it = id_to_app_list_index.find(app->id());
+ const auto& it = id_to_app_list_index.find(app->id());
// If it's in a folder, it won't be in |id_to_app_list_index|. Rank
// those as if they are at the end of the list.
- size_t app_list_index =
- it == id_to_app_list_index.end() ? apps_.size() : (*it).second;
- if (app_list_index > apps_.size())
- app_list_index = apps_.size();
+ const size_t app_list_index = (it == id_to_app_list_index.end())
+ ? apps_size
+ : std::min(apps_size, it->second);
result->set_relevance(kUnlaunchedAppRelevanceStepSize *
- (apps_.size() - app_list_index));
+ (apps_size - app_list_index));
} else {
result->UpdateFromLastLaunchedOrInstalledTime(clock_->Now(), time);
}
- Add(std::move(result));
+ new_results.emplace_back(std::move(result));
}
} else {
+ const TokenizedString query_terms(query_);
for (auto& app : apps_) {
std::unique_ptr<AppResult> result = app->data_source()->CreateResult(
app->id(), list_controller_, top_level_item_list_, false);
TokenizedStringMatch match;
- if (!match.Calculate(query_terms, app->indexed_name()))
+ TokenizedString* indexed_name = app->GetTokenizedIndexedName();
+ if (!match.Calculate(query_terms, *indexed_name))
continue;
- result->UpdateFromMatch(app->indexed_name(), match);
- Add(std::move(result));
+ result->UpdateFromMatch(*indexed_name, match);
+ new_results.emplace_back(std::move(result));
}
}
+ SwapResults(&new_results);
+
update_results_factory_.InvalidateWeakPtrs();
}

Powered by Google App Engine
This is Rietveld 408576698