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

Unified Diff: tools/perf/metrics/discrepancy.py

Issue 23506030: telemetry: Add new metrics to smoothness benchmark. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 7 years, 3 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
« no previous file with comments | « tools/perf/measurements/smoothness.py ('k') | tools/perf/metrics/discrepancy_unittest.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/perf/metrics/discrepancy.py
diff --git a/tools/perf/metrics/discrepancy.py b/tools/perf/metrics/discrepancy.py
new file mode 100644
index 0000000000000000000000000000000000000000..8ec3d2c85de9b3d4d3179769810e89211e0f2f97
--- /dev/null
+++ b/tools/perf/metrics/discrepancy.py
@@ -0,0 +1,110 @@
+# Copyright 2013 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import bisect
+import math
+
+def Clamp(value, low=0.0, high=1.0):
+ return min(max(value, low), high)
+
+def NormalizeSamples(samples):
+ ''' Sort the N samples, and map them linearly to the range [0,1] such that the
+ first sample is 0.5/N and the last sample is (N-0.5)/N. Background: the
+ discrepancy of the sample set i/(N-1); i=0,...,N-1 is 2/N, twice the
+ discrepancy of the sample set (i+1/2)/N; i=0,...,N-1. In our case we
+ don't want to distinguish between these two cases, as our original domain
+ is not bounded (it is for Monte Carlo integration, where discrepancy was
+ first used).
+ '''
+ samples = sorted(samples)
+ low = min(samples)
+ high = max(samples)
+ new_low = 0.5 / len(samples)
+ new_high = (len(samples)-0.5) / len(samples)
+ scale = (new_high - new_low) / (high - low)
+ for i in xrange(0, len(samples)):
+ samples[i] = float(samples[i] - low) * scale + new_low
+ return samples, scale
+
+def Discrepancy(samples, interval_multiplier = 10000):
+ ''' Compute the discrepancy of a set of 1D samples from the unit interval
+ [0,1]. The samples must be sorted.
+
+ http://en.wikipedia.org/wiki/Low-discrepancy_sequence
+ http://mathworld.wolfram.com/Discrepancy.html
+ '''
+ if (len(samples) < 3):
+ return 0
+
+ max_local_discrepancy = 0
+ locations = []
+ # For each location, stores the number of samples less than that location.
+ left = []
+ # For each location, stores the number of samples less than or equal to that
+ # location.
+ right = []
+
+ interval_count = len(samples) * interval_multiplier
+ # Compute number of locations the will roughly result in the requested number
+ # of intervals.
+ location_count = int(math.ceil(math.sqrt(interval_count*2)))
+ inv_sample_count = 1.0 / len(samples)
+
+ # Generate list of equally spaced locations.
+ for i in xrange(0, location_count):
+ location = float(i) / (location_count-1)
+ locations.append(location)
+ left.append(bisect.bisect_left(samples, location))
+ right.append(bisect.bisect_right(samples, location))
+
+ # Iterate over the intervals defined by any pair of locations.
+ for i in xrange(0, len(locations)):
+ for j in xrange(i, len(locations)):
+ # Compute length of interval and number of samples in the interval.
+ length = locations[j] - locations[i]
+ count = right[j] - left[i]
+
+ # Compute local discrepancy and update max_local_discrepancy.
+ local_discrepancy = abs(float(count)*inv_sample_count - length)
+ max_local_discrepancy = max(local_discrepancy, max_local_discrepancy)
+
+ return max_local_discrepancy
+
+def FrameDiscrepancy(frame_timestamps, absolute = True,
+ interval_multiplier = 10000):
+ ''' A discrepancy based metric for measuring jank.
+
+ FrameDiscrepancy quantifies the largest area of jank observed in a series
+ of timestamps. Note that this is different form metrics based on the
+ max_frame_time. For example, the time stamp series A = [0,1,2,3,5,6] and
+ B = [0,1,2,3,5,7] have the same max_frame_time = 2, but
+ Discrepancy(B) > Discrepancy(A).
+
+ Two variants of discrepancy can be computed:
+
+ Relative discrepancy is following the original definition of
+ discrepancy. It characterized the largest area of jank, relative to the
+ duration of the entire time stamp series. We normalize the raw results,
+ because the best case discrepancy for a set of N samples is 1/N (for
+ equally spaced samples), and we want our metric to report 0.0 in that
+ case.
+
+ Absolute discrepancy also characterizes the largest area of jank, but its
+ value wouldn't change (except for imprecisions due to a low
+ interval_multiplier) if additional 'good' frames were added to an
+ exisiting list of time stamps. Its range is [0,inf] and the unit is
+ milliseconds.
+
+ The time stamp series C = [0,2,3,4] and D = [0,2,3,4,5] have the same
+ absolute discrepancy, but D has lower relative discrepancy than C.
+ '''
+ samples, sample_scale = NormalizeSamples(frame_timestamps)
+ discrepancy = Discrepancy(samples, interval_multiplier)
+ inv_sample_count = 1.0 / len(samples)
+ if absolute:
+ # Compute absolute discrepancy
+ discrepancy /= sample_scale
+ else:
+ # Compute relative discrepancy
+ discrepancy = Clamp((discrepancy-inv_sample_count) / (1.0-inv_sample_count))
+ return discrepancy
« no previous file with comments | « tools/perf/measurements/smoothness.py ('k') | tools/perf/metrics/discrepancy_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698