1<!DOCTYPE html>
2<!--
3Copyright (c) 2015 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/tracing/base/statistics.html">
9<link rel="import" href="/tracing/metrics/metric_registry.html">
10<link rel="import" href="/tracing/metrics/system_health/utils.html">
11<link rel="import" href="/tracing/model/user_model/animation_expectation.html">
12<link rel="import" href="/tracing/model/user_model/idle_expectation.html">
13<link rel="import" href="/tracing/value/numeric.html">
14<link rel="import" href="/tracing/value/value.html">
15
16<script>
17'use strict';
18
19tr.exportTo('tr.metrics.sh', function() {
20  var UNIT = tr.v.Unit.byName.normalizedPercentage_biggerIsBetter;
21
22  var DESCRIPTION = 'Normalized CPU budget consumption';
23
24  function EfficiencyMetric(valueList, model) {
25    var scores = [];
26
27    model.userModel.expectations.forEach(function(ue) {
28      var options = {};
29      options.description = DESCRIPTION;
30
31      var groupingKeys = {};
32      groupingKeys.userExpectationStableId = ue.stableId;
33      groupingKeys.userExpectationStageTitle = ue.stageTitle;
34      groupingKeys.userExpectationInitiatorTitle = ue.initiatorTitle;
35
36      var score = undefined;
37
38      if ((ue.totalCpuMs === undefined) ||
39          (ue.totalCpuMs == 0))
40        return;
41
42      var cpuFractionBudget = tr.b.Range.fromExplicitRange(0.5, 1.5);
43
44      if (ue instanceof tr.model.um.IdleExpectation) {
45        cpuFractionBudget = tr.b.Range.fromExplicitRange(0.1, 1);
46      } else if (ue instanceof tr.model.um.AnimationExpectation) {
47        cpuFractionBudget = tr.b.Range.fromExplicitRange(1, 2);
48      }
49
50      var cpuMsBudget = tr.b.Range.fromExplicitRange(
51          ue.duration * cpuFractionBudget.min,
52          ue.duration * cpuFractionBudget.max);
53      var normalizedCpu = tr.b.normalize(
54          ue.totalCpuMs, cpuMsBudget.min, cpuMsBudget.max);
55      score = 1 - tr.b.clamp(normalizedCpu, 0, 1);
56
57      scores.push(score);
58
59      valueList.addValue(new tr.v.NumericValue(
60          model.canonicalUrlThatCreatedThisTrace, 'efficiency',
61          new tr.v.ScalarNumeric(UNIT, score),
62          options, groupingKeys));
63    });
64
65    // Manually reduce scores.
66    // https://github.com/catapult-project/catapult/issues/2036
67
68    var options = {};
69    options.description = DESCRIPTION;
70    var groupingKeys = {};
71    var overallScore = tr.b.Statistics.weightedMean(
72        scores, tr.metrics.sh.perceptualBlend);
73    if (overallScore === undefined)
74      return;
75
76    valueList.addValue(new tr.v.NumericValue(
77        model.canonicalUrlThatCreatedThisTrace, 'efficiency',
78        new tr.v.ScalarNumeric(UNIT, overallScore),
79        options, groupingKeys));
80  }
81
82  EfficiencyMetric.prototype = {
83    __proto__: Function.prototype
84  };
85
86  tr.metrics.MetricRegistry.register(EfficiencyMetric);
87
88  return {
89    EfficiencyMetric: EfficiencyMetric
90  };
91});
92</script>
93