Commit 72ce65b0 authored by Hailey Wang's avatar Hailey Wang Committed by Commit Bot

[PM] Add calculation for age score

Add calculation method for scoring of a tab depending on it's last
visibility change time.

This will be used for calculating tab score in future cl.

Bug: 1059341
Change-Id: Ib6c9534bc6f47d73063a436a2a31f436c77ae872
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2136031
Commit-Queue: Hailey Wang <haileywang@google.com>
Reviewed-by: default avatarSébastien Marchand <sebmarchand@chromium.org>
Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Cr-Commit-Position: refs/heads/master@{#757922}
parent 47e78d09
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/performance_manager/graph/policies/background_tab_loading_policy_helpers.h" #include "chrome/browser/performance_manager/graph/policies/background_tab_loading_policy_helpers.h"
#include <math.h>
#include "base/logging.h" #include "base/logging.h"
namespace performance_manager { namespace performance_manager {
...@@ -34,6 +37,47 @@ size_t CalculateMaxSimultaneousTabLoads(size_t lower_bound, ...@@ -34,6 +37,47 @@ size_t CalculateMaxSimultaneousTabLoads(size_t lower_bound,
return loads; return loads;
} }
float CalculateAgeScore(double last_visibility_change_seconds) {
// TODO(crbug.com/1059341): Determine via an experiment whether tabs could
// simply be sorted by descending order of last visibility, instead of using
// an opaque score.
// Cap absolute values less than 1 so that the inverse will be between -1
// and 1.
double score = last_visibility_change_seconds;
if (fabs(score) < 1.0f) {
if (score > 0)
score = 1;
else
score = -1;
}
DCHECK_LE(1.0f, fabs(score));
// Invert the score (1 / score).
// Really old (infinity) maps to 0 (lowest priority).
// Really young positive age (1) maps to 1 (moderate priority).
// A little in the future (-1) maps to -1 (moderate priority).
// Really far in the future (-infinity) maps to 0 (highest priority).
// Shifting negative scores from [-1, 0] to [1, 2] keeps the scores increasing
// with priority.
if (score < 0) {
score = 2.0 + 1.0 / score;
} else {
score = 1.0 / score;
}
DCHECK_LE(0.0, score);
DCHECK_GE(2.0, score);
// Rescale the age score to the range [0, 1] so that it can be added to the
// category scores already calculated. Divide by 2 + epsilon so that no
// score will end up rounding up to 1.0, but instead be capped at 0.999.
score /= 2.002;
DCHECK_LE(0.0, score);
DCHECK_GT(1.0, score);
return score;
}
} // namespace policies } // namespace policies
} // namespace performance_manager } // namespace performance_manager
...@@ -18,6 +18,11 @@ size_t CalculateMaxSimultaneousTabLoads(size_t lower_bound, ...@@ -18,6 +18,11 @@ size_t CalculateMaxSimultaneousTabLoads(size_t lower_bound,
size_t cores_per_load, size_t cores_per_load,
size_t num_cores); size_t num_cores);
// Calculates a score for the "age" of the tab. This is a value between 0
// (inclusive) and 1 (exclusive), where higher values are attributed to newer
// tabs.
float CalculateAgeScore(double last_visibility_change_seconds);
} // namespace policies } // namespace policies
} // namespace performance_manager } // namespace performance_manager
......
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
#include "chrome/browser/performance_manager/graph/policies/background_tab_loading_policy_helpers.h" #include "chrome/browser/performance_manager/graph/policies/background_tab_loading_policy_helpers.h"
#include <math.h>
#include "base/rand_util.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace performance_manager { namespace performance_manager {
...@@ -49,6 +53,87 @@ TEST_F(BackgroundTabLoadingPolicyHelpersTest, ...@@ -49,6 +53,87 @@ TEST_F(BackgroundTabLoadingPolicyHelpersTest,
0 /* cores_per_load */, 4 /* cores */)); 0 /* cores_per_load */, 4 /* cores */));
} }
TEST_F(BackgroundTabLoadingPolicyHelpersTest, CalculateAgeScore) {
// Generate a bunch of random tab age data.
std::vector<std::pair<base::TimeDelta, float>> tab_age_score;
tab_age_score.reserve(1000);
// Generate some known edge cases.
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromMilliseconds(-1001), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromMilliseconds(-1000), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromMilliseconds(-999), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromMilliseconds(-500), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromMilliseconds(0), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromMilliseconds(500), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromMilliseconds(999), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromMilliseconds(1000), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromMilliseconds(1001), 0.0));
// Generate a logarithmic selection of ages to test the whole range.
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromSeconds(-1000000), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromSeconds(-100000), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromSeconds(-10000), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromSeconds(-1000), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromSeconds(-100), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromSeconds(-10), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromSeconds(10), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromSeconds(100), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromSeconds(1000), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromSeconds(10000), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromSeconds(100000), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromSeconds(1000000), 0.0));
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromSeconds(10000000), 0.0));
constexpr int kMonthInSeconds = 60 * 60 * 24 * 31;
// Generate a bunch more random ages.
for (size_t i = tab_age_score.size(); i < 1000; ++i) {
tab_age_score.push_back(
std::make_pair(base::TimeDelta::FromSeconds(
base::RandInt(-kMonthInSeconds, kMonthInSeconds)),
0.0));
}
// Calculate the tab scores.
for (auto age_score : tab_age_score) {
age_score.second = CalculateAgeScore(age_score.first.InSecondsF());
}
// Sort tab scores by increasing last active time.
std::sort(tab_age_score.begin(), tab_age_score.end(),
[](const std::pair<base::TimeDelta, float>& tab1,
const std::pair<base::TimeDelta, float>& tab2) {
return tab1.first < tab2.first;
});
// The scores should be in decreasing order (>= is necessary because some
// last active times collapse to the same score).
for (size_t i = 1; i < tab_age_score.size(); ++i)
ASSERT_GE(tab_age_score[i - 1].second, tab_age_score[i].second);
}
} // namespace policies } // namespace policies
} // namespace performance_manager } // namespace performance_manager
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment