haikuwebkit/Websites/perf.webkit.org/unit-tests/statistics-tests.js

605 lines
36 KiB
JavaScript
Raw Permalink Normal View History

Add unit tests for config.json and statistics.js https://bugs.webkit.org/show_bug.cgi?id=155626 Reviewed by Darin Adler. Added mocha unit tests for statistics.js and validating config.json. For segmentations, I've extracted real data from our internal perf dashboard. Also fixed some bugs covered by these new tests. * public/shared/statistics.js: (Statistics.movingAverage): Fixed a bug that forwardWindowSize was never used. (Statistics.exponentialMovingAverage): Fixed the bug that the moving average starts at 0. It should start at the first value instead. (.splitIntoSegmentsUntilGoodEnough): Fixed the bug that we may try to segment a time series into more parts than there are data points. Clearly, that doesn't make any sense. (.findOptimalSegmentation): Renamed local variables so that they're more descriptive, and rewrote the debugging code was the old code was emitting some useless data. Also fixed the bug that the length of "segmentation" was off by one (we need segmentCount + 1 elements in the array sine we always include the start of the first segment = 0 and the end of the last segment = values.length). (.SampleVarianceUpperTriangularMatrix): (Statistics): Modernized the export code. * tools/js: Added. * tools/js/config.js: Added. (Config): Added. (Config.prototype.configFilePath): Added. (Config.prototype.value): Added. (Config.prototype.path): Added. * tools/js/database.js: Added. (Database): Added. (Database.prototype.connect): Added. (Database.prototype.disconnect): Added. * unit-tests: Added. * unit-tests/checkconfig.js: Added. Validates config.json. This is useful while setting up a local instance of the perf dashboard. * unit-tests/statistics-tests.js: Added. (assert.almostEqual): Added. Asserts that two floating values are within a given significant digits. (.stdev): (.delta): (.computeWelchsT): Canonical link: https://commits.webkit.org/173743@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198386 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-03-18 07:15:54 +00:00
"use strict";
var assert = require('assert');
var Statistics = require('../public/shared/statistics.js');
Always show segmentation on v3 charts page https://bugs.webkit.org/show_bug.cgi?id=160576 Rubber-stamped by Chris Dumez. Added "Trend Lines" popover to select and customize a moving average or a segmentation to show on charts page and made Schwarz criterion segmentation the default trend line for all charts. Because computing the segmentation is expensive, we use WebWorker to parallelize the computation via AsyncTask. We also compute and cache the segmentation for each cluster separately to avoid processing the entire measurement set as that could take 10-20s total, which was a huge problem in v2 UI. v3 UI's approach is more incremental and even opens up an opportunity to cache the results in the server side. Also brought back "shading" for the confidence interval drawing as done in v1 and v2 UI. * public/shared/statistics.js: (Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion): Added segmentCountWeight and gridSize as arguments to customize the algorithm. (Statistics.splitIntoSegmentsUntilGoodEnough): Takes segmentCountWeight as BirgeAndMassartC. * public/v3/async-task.js: Added. (AsyncTask): Added. This class represents a task such as computing segmentation to be executed in a worker. (AsyncTask.prototype.execute): Added. Returns a promise that gets resolved when the specified task completes. (AsyncTaskWorker.waitForAvailableWorker): Added. Calls the given callback with the first available worker. When all workers are processing some tasks, it waits until one becomes available by putting the callback into a queue. _didRecieveMessage pops an item out of this queue when a worker completes a task. We don't use a promise here because calling this function multiple times synchronously could result in all the returned promises getting resolved with the same worker as none of the callers get to lock away the first available worker until the end of the current micro-task. (AsyncTaskWorker._makeWorkerEventuallyAvailable): Added. A helper function for waitForAvailableWorker. Start a new worker if the number of workers we've started is less than the number of extra cores (e.g. 7 if there are 8 cores on the machine). Avoid starting a new worker if we've started a new worker within the last 50 ms since starting a new worker takes some time. (AsyncTaskWorker._findAvailableWorker): Added. Finds a worker that's available right now if there is any. (AsyncTaskWorker): Added. An instance of AsyncTaskWorker represents a Web worker. (AsyncTaskWorker.prototype.id): Added. (AsyncTaskWorker.prototype.sendTask): Added. Sends a task represented by AsyncTask to the worker. (AsyncTaskWorker.prototype._didRecieveMessage): Added. This function gets called when the current task completes in the worker. Pop the next callback if some caller of waitForAvailableWorker is still waiting. Otherwise stop the worker after one second of waiting to avoid worker churning. (AsyncTaskWorker.workerDidRecieveMessage): Added. Called by onmessage on the worker. Executes the specified task and sends back a message upon completion with the appropriate timing data. * public/v3/components/chart-pane-base.js: (ChartPaneBase.prototype.configure): Uses _createSourceList. (ChartPaneBase.prototype._createSourceList): Added. Extracted from configure to customize the source list for the main chart and the overview chart. (ChartPaneBase.prototype._updateSourceList): Uses _createSourceList. * public/v3/components/chart-styles.js: (ChartStyles.createSourceList): Added a boolean showPoint as an extra argument. This specifies whether circles are drawn for each data point. (ChartStyles.baselineStyle): Added styles for foreground lines and background lines. They're used for trend lines and underlying raw data respectively when trend lines are shown. (ChartStyles.targetStyle): Ditto. (ChartStyles.currentStyle): Ditto. * public/v3/components/time-series-chart.js: (TimeSeriesChart): Added _trendLines, _renderedTrendLines, and _fetchedTimeSeries as instance variables. (TimeSeriesChart.prototype.setSourceList): Clear _fetchedTimeSeries before calling setSourceList for consistency. (TimeSeriesChart.prototype.sourceList): Added. (TimeSeriesChart.prototype.clearTrendLines): Added. (TimeSeriesChart.prototype.setTrendLine): Added. Preserves the existing trend lines for other sources. This is necessary because segmentation for "current" and "baseline" lines may become available at different times, and we don't want to clear one or the other when setting one. (TimeSeriesChart.prototype._layout): Added a call to _ensureTrendLines. (TimeSeriesChart.prototype._renderChartContent): Call _renderTimeSeries for trend lines. Trend lines are always foreground lines and "regular" raw data points are drawn as background if there are trend lines. (TimeSeriesChart.prototype._renderTimeSeries): Added layerName as an argument. It could be an empty string, "foreground", or "background". Draw a "shade" just like v1 and v2 UI instead of vertical lines for the confidence intervals. Pick "foreground", "background", or "regular" chart style based on layerName. Also avoid drawing data points when *PointRadius is set to zero to reduce the runtime of this function. (TimeSeriesChart.prototype._sourceOptionWithFallback): Added. (TimeSeriesChart.prototype._ensureSampledTimeSeries): When *PointRadius is 0, show as many points as there are x coordinates as a fallback instead of showing every point. (TimeSeriesChart.prototype._ensureTrendLines): Added. Returns true if the chart contents haven't been re-rendered since the last update to trend lines. This flag is unset by setTrendLine. * public/v3/index.html: * public/v3/models/measurement-cluster.js: (MeasurementCluster.prototype.addToSeries): Store the data points' index to idMap to help aid MeasurementSet's _cachedClusterSegmentation efficiently re-create the segmentation from the cache. * public/v3/models/measurement-set.js: (MeasurementSet): Added _segmentationCache as an instance variable. (MeasurementSet.prototype.fetchSegmentation): Added. Calls _cachedClusterSegmentation on each cluster, and constructs the time series representation of the segmentation from the results. (MeasurementSet.prototype._cachedClusterSegmentation): Computes and caches the segmentation for each cluster. The cache of segmentation stores ID of each measurement set at which segment changes instead of its index since the latter could change in any moment when a new test result is reported, or an existing test result is removed from the time series; e.g. when it's marked as an outlier. (MeasurementSet.prototype._validateSegmentationCache): Added. Checks whether the cached segmentation's name and its parameters match that of the requested one. (MeasurementSet.prototype._invokeSegmentationAlgorithm): Added. Invokes the segmentation algorithm either in the main thread or in a Web worker via AsyncTask API based on the size of the time series. While parallelizing the work is beneficial when the data set is large, the overhead can add up if we keep processing a very small data set in a worker. * public/v3/models/time-series.js: Made the file compatible with Node. (TimeSeries.prototype.length): Added. (TimeSeries.prototype.valuesBetweenRange): Added. * public/v3/pages/chart-pane.js: (createTrendLineExecutableFromAveragingFunction): Added. (ChartTrendLineTypes): Added. Similar to StatisticsStrategies (statistics-strategies.js) in v2 UI. (ChartPane): Added _trendLineType, _trendLineParameters, _trendLineVersion, and _renderedTrendLineOptions as instance variables. (ChartPane.prototype.serializeState): Serialize the trend line option. This format is compatible with v2 UI. (ChartPane.prototype.updateFromSerializedState): Ditto. Parsing is compatible with v2 UI except that we now have the default trend line set when the specified ID doesn't match an existing type ID. (ChartPane.prototype._renderActionToolbar): Added a call to _renderTrendLinePopover. This is the popover that specifies the type of a trend line to show as well as its parameters. (ChartPane.prototype._renderTrendLinePopover): Added. A popover for specifying and customizing a trend line. (ChartPane.prototype._trendLineTypeDidChange): Added. Called when a new trend line is selected. (ChartPane.prototype._defaultParametersForTrendLine): Added. (ChartPane.prototype._trendLineParameterDidChange): Added. Called when the trend lines' parameters are changed. (ChartPane.prototype._didFetchData): Added. Overrides the one in ChartPaneBase to trigger a trend line update. (ChartPane.prototype._updateTrendLine): Added. Update the trend line. Since segmentation can take an arbitrary long time, avoid updating trend lines if this function had been called again (possibly for a different trend line type or with different parameters) before the results become available; hence the versioning. (ChartPane.paneHeaderTemplate): Added the trend line popover. (ChartPane.cssTemplate): Added styles for the trend line popover. Also use a more opaque background color behind popovers when the -webkit-backdrop-filter property is not supported. * public/v3/pages/dashboard-page.js: (DashboardPage.prototype._createChartForCell): Call createSourceList with showPoints set to true to preserve the existing behavior. * tools/js/v3-models.js: Include TimeSeries object. * unit-tests/measurement-set-tests.js: Added two test cases for MeasurementSet's fetchSegmentation. * unit-tests/resources/almost-equal.js: Added. (almostEqual): Extracted out of statistics-tests.js. * unit-tests/statistics-tests.js: Canonical link: https://commits.webkit.org/178822@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@204296 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-08-09 21:22:54 +00:00
if (!assert.almostEqual)
assert.almostEqual = require('./resources/almost-equal.js');
Add unit tests for config.json and statistics.js https://bugs.webkit.org/show_bug.cgi?id=155626 Reviewed by Darin Adler. Added mocha unit tests for statistics.js and validating config.json. For segmentations, I've extracted real data from our internal perf dashboard. Also fixed some bugs covered by these new tests. * public/shared/statistics.js: (Statistics.movingAverage): Fixed a bug that forwardWindowSize was never used. (Statistics.exponentialMovingAverage): Fixed the bug that the moving average starts at 0. It should start at the first value instead. (.splitIntoSegmentsUntilGoodEnough): Fixed the bug that we may try to segment a time series into more parts than there are data points. Clearly, that doesn't make any sense. (.findOptimalSegmentation): Renamed local variables so that they're more descriptive, and rewrote the debugging code was the old code was emitting some useless data. Also fixed the bug that the length of "segmentation" was off by one (we need segmentCount + 1 elements in the array sine we always include the start of the first segment = 0 and the end of the last segment = values.length). (.SampleVarianceUpperTriangularMatrix): (Statistics): Modernized the export code. * tools/js: Added. * tools/js/config.js: Added. (Config): Added. (Config.prototype.configFilePath): Added. (Config.prototype.value): Added. (Config.prototype.path): Added. * tools/js/database.js: Added. (Database): Added. (Database.prototype.connect): Added. (Database.prototype.disconnect): Added. * unit-tests: Added. * unit-tests/checkconfig.js: Added. Validates config.json. This is useful while setting up a local instance of the perf dashboard. * unit-tests/statistics-tests.js: Added. (assert.almostEqual): Added. Asserts that two floating values are within a given significant digits. (.stdev): (.delta): (.computeWelchsT): Canonical link: https://commits.webkit.org/173743@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198386 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-03-18 07:15:54 +00:00
describe('assert.almostEqual', function () {
it('should not throw when values are identical', function () {
assert.doesNotThrow(function () { assert.almostEqual(1, 1); });
});
it('should not throw when values are close', function () {
assert.doesNotThrow(function () { assert.almostEqual(1.10, 1.107, 2); });
assert.doesNotThrow(function () { assert.almostEqual(1256.7, 1256.72, 4); });
});
it('should throw when values are not close', function () {
assert.throws(function () { assert.almostEqual(1.10, 1.27, 2); });
assert.throws(function () { assert.almostEqual(735.4, 735.6, 4); });
});
});
describe('Statistics', function () {
describe('min', function () {
it('should find the mininum value', function () {
assert.equal(Statistics.min([1, 2, 3, 4]), 1);
assert.equal(Statistics.min([4, 3, 2, 1]), 1);
assert.equal(Statistics.min([2000, 20, 200]), 20);
assert.equal(Statistics.min([0.3, 0.06, 0.5]), 0.06);
assert.equal(Statistics.min([-0.3, 0.06, 0.5]), -0.3);
assert.equal(Statistics.min([-0.3, 0.06, 0.5, Infinity]), -0.3);
assert.equal(Statistics.min([-0.3, 0.06, 0.5, -Infinity]), -Infinity);
assert.equal(Statistics.min([]), Infinity);
});
});
describe('max', function () {
it('should find the mininum value', function () {
assert.equal(Statistics.max([1, 2, 3, 4]), 4);
assert.equal(Statistics.max([4, 3, 2, 1]), 4);
assert.equal(Statistics.max([2000, 20, 200]), 2000);
assert.equal(Statistics.max([0.3, 0.06, 0.5]), 0.5);
assert.equal(Statistics.max([-0.3, 0.06, 0.5]), 0.5);
assert.equal(Statistics.max([-0.3, 0.06, 0.5, Infinity]), Infinity);
assert.equal(Statistics.max([-0.3, 0.06, 0.5, -Infinity]), 0.5);
assert.equal(Statistics.max([]), -Infinity);
});
});
describe('sum', function () {
it('should find the sum of values', function () {
assert.equal(Statistics.sum([1, 2, 3, 4]), 10);
assert.equal(Statistics.sum([4, 3, 2, 1]), 10);
assert.equal(Statistics.sum([2000, 20, 200]), 2220);
assert.equal(Statistics.sum([0.3, 0.06, 0.5]), 0.86);
assert.equal(Statistics.sum([-0.3, 0.06, 0.5]), 0.26);
assert.equal(Statistics.sum([-0.3, 0.06, 0.5, Infinity]), Infinity);
assert.equal(Statistics.sum([-0.3, 0.06, 0.5, -Infinity]), -Infinity);
assert.equal(Statistics.sum([]), 0);
});
});
describe('squareSum', function () {
it('should find the square sum of values', function () {
assert.equal(Statistics.squareSum([1, 2, 3, 4]), 30);
assert.equal(Statistics.squareSum([4, 3, 2, 1]), 30);
assert.equal(Statistics.squareSum([2000, 20, 200]), 2000 * 2000 + 20 * 20 + 200* 200);
assert.equal(Statistics.squareSum([0.3, 0.06, 0.5]), 0.09 + 0.0036 + 0.25);
assert.equal(Statistics.squareSum([-0.3, 0.06, 0.5]), 0.09 + 0.0036 + 0.25);
assert.equal(Statistics.squareSum([-0.3, 0.06, 0.5, Infinity]), Infinity);
assert.equal(Statistics.squareSum([-0.3, 0.06, 0.5, -Infinity]), Infinity);
assert.equal(Statistics.squareSum([]), 0);
});
});
describe('sampleStandardDeviation', function () {
function stdev(values) {
return Statistics.sampleStandardDeviation(values.length,
Statistics.sum(values), Statistics.squareSum(values));
}
it('should find the standard deviation of values', function () {
assert.almostEqual(stdev([1, 2, 3, 4]), 1.2909944);
assert.almostEqual(stdev([4, 3, 2, 1]), 1.2909944);
assert.almostEqual(stdev([2000, 20, 200]), 1094.89726);
assert.almostEqual(stdev([0.3, 0.06, 0.5]), 0.220302822);
assert.almostEqual(stdev([-0.3, 0.06, 0.5]), 0.40066611203);
assert.almostEqual(stdev([-0.3, 0.06, 0.5, Infinity]), NaN);
assert.almostEqual(stdev([-0.3, 0.06, 0.5, -Infinity]), NaN);
assert.almostEqual(stdev([]), 0);
});
});
describe('confidenceIntervalDelta', function () {
it('should find the p-value of values using Student\'s t distribution', function () {
function delta(values, probabilty) {
return Statistics.confidenceIntervalDelta(probabilty, values.length,
Statistics.sum(values), Statistics.squareSum(values));
}
// https://onlinecourses.science.psu.edu/stat414/node/199
var values = [118, 115, 125, 110, 112, 130, 117, 112, 115, 120, 113, 118, 119, 122, 123, 126];
assert.almostEqual(delta(values, 0.95), 3.015, 3);
// Following values are computed using Excel Online's STDEV and CONFIDENCE.T
Show t-test results based on individual measurements to analysis task page. https://bugs.webkit.org/show_bug.cgi?id=188425 Reviewed by Ryosuke Niwa. Added comparison for individual iterations in analysis task page. Added comparison for individual iterations for notification on A/B tests completion. Refactored t-distribution inverse lookup to any degree of freedom with 5 significant figures. * public/shared/statistics.js: Refactored t-distribution inverse lookup function and adapted this change to all invocations. (Statistics.new.this.supportedConfidenceIntervalProbabilities): (Statistics.new.this.supportedOneSideTTestProbabilities): (Statistics.new.this.confidenceIntervalDelta): (Statistics.new.sampleMeanAndVarianceForMultipleSamples): (Statistics.new.this.probabilityRangeForWelchsT): (Statistics.new.this.probabilityRangeForWelchsTFromTwoSampleSets): (Statistics.new.this._determinetwoSidedProbabilityBoundaryForWelchsT): (Statistics.new.this.computeWelchsT): (Statistics.new.this._computeWelchsTFromStatistics): (Statistics.new.this.minimumTForOneSidedProbability): Function that does t-distribution inverse lookup. * public/v3/components/analysis-results-viewer.js: Adapted TestGroup.compareTestResults change. (AnalysisResultsViewer.TestGroupStackingBlock.prototype._measurementsForCommitSet): (AnalysisResultsViewer.TestGroupStackingBlock.prototype._computeTestGroupStatus): (AnalysisResultsViewer.TestGroupStackingBlock.prototype._valuesForCommitSet): Deleted. * public/v3/components/test-group-results-viewer.js: Show both comparisions for both individual and mean. (TestGroupResultsViewer.prototype._renderResultsTable): (TestGroupResultsViewer.prototype._buildRowForMetric.): (TestGroupResultsViewer.prototype._buildValueMap): * public/v3/models/test-group.js: (TestGroup.compareTestResults): Added comparison for individual iterations. * tools/js/test-group-result-page.js: (TestGroupResultPage.prototype._constructTableForMetric): (TestGroupResultPage.prototype.get styleTemplate): (TestGroupResultPage): (TestGroupResultPage.prototype._URLForAnalysisTask): Renamed to '_resultsForTestGroup' * unit-tests/statistics-tests.js: Updated and added unit tests. Canonical link: https://commits.webkit.org/203958@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235255 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-23 23:11:10 +00:00
assert.almostEqual(delta([1, 2, 3, 4], 0.8), 1.057159, 4);
assert.almostEqual(delta([1, 2, 3, 4], 0.9), 1.519090, 4);
assert.almostEqual(delta([1, 2, 3, 4], 0.95), 2.054260, 4);
Add unit tests for config.json and statistics.js https://bugs.webkit.org/show_bug.cgi?id=155626 Reviewed by Darin Adler. Added mocha unit tests for statistics.js and validating config.json. For segmentations, I've extracted real data from our internal perf dashboard. Also fixed some bugs covered by these new tests. * public/shared/statistics.js: (Statistics.movingAverage): Fixed a bug that forwardWindowSize was never used. (Statistics.exponentialMovingAverage): Fixed the bug that the moving average starts at 0. It should start at the first value instead. (.splitIntoSegmentsUntilGoodEnough): Fixed the bug that we may try to segment a time series into more parts than there are data points. Clearly, that doesn't make any sense. (.findOptimalSegmentation): Renamed local variables so that they're more descriptive, and rewrote the debugging code was the old code was emitting some useless data. Also fixed the bug that the length of "segmentation" was off by one (we need segmentCount + 1 elements in the array sine we always include the start of the first segment = 0 and the end of the last segment = values.length). (.SampleVarianceUpperTriangularMatrix): (Statistics): Modernized the export code. * tools/js: Added. * tools/js/config.js: Added. (Config): Added. (Config.prototype.configFilePath): Added. (Config.prototype.value): Added. (Config.prototype.path): Added. * tools/js/database.js: Added. (Database): Added. (Database.prototype.connect): Added. (Database.prototype.disconnect): Added. * unit-tests: Added. * unit-tests/checkconfig.js: Added. Validates config.json. This is useful while setting up a local instance of the perf dashboard. * unit-tests/statistics-tests.js: Added. (assert.almostEqual): Added. Asserts that two floating values are within a given significant digits. (.stdev): (.delta): (.computeWelchsT): Canonical link: https://commits.webkit.org/173743@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198386 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-03-18 07:15:54 +00:00
Show t-test results based on individual measurements to analysis task page. https://bugs.webkit.org/show_bug.cgi?id=188425 Reviewed by Ryosuke Niwa. Added comparison for individual iterations in analysis task page. Added comparison for individual iterations for notification on A/B tests completion. Refactored t-distribution inverse lookup to any degree of freedom with 5 significant figures. * public/shared/statistics.js: Refactored t-distribution inverse lookup function and adapted this change to all invocations. (Statistics.new.this.supportedConfidenceIntervalProbabilities): (Statistics.new.this.supportedOneSideTTestProbabilities): (Statistics.new.this.confidenceIntervalDelta): (Statistics.new.sampleMeanAndVarianceForMultipleSamples): (Statistics.new.this.probabilityRangeForWelchsT): (Statistics.new.this.probabilityRangeForWelchsTFromTwoSampleSets): (Statistics.new.this._determinetwoSidedProbabilityBoundaryForWelchsT): (Statistics.new.this.computeWelchsT): (Statistics.new.this._computeWelchsTFromStatistics): (Statistics.new.this.minimumTForOneSidedProbability): Function that does t-distribution inverse lookup. * public/v3/components/analysis-results-viewer.js: Adapted TestGroup.compareTestResults change. (AnalysisResultsViewer.TestGroupStackingBlock.prototype._measurementsForCommitSet): (AnalysisResultsViewer.TestGroupStackingBlock.prototype._computeTestGroupStatus): (AnalysisResultsViewer.TestGroupStackingBlock.prototype._valuesForCommitSet): Deleted. * public/v3/components/test-group-results-viewer.js: Show both comparisions for both individual and mean. (TestGroupResultsViewer.prototype._renderResultsTable): (TestGroupResultsViewer.prototype._buildRowForMetric.): (TestGroupResultsViewer.prototype._buildValueMap): * public/v3/models/test-group.js: (TestGroup.compareTestResults): Added comparison for individual iterations. * tools/js/test-group-result-page.js: (TestGroupResultPage.prototype._constructTableForMetric): (TestGroupResultPage.prototype.get styleTemplate): (TestGroupResultPage): (TestGroupResultPage.prototype._URLForAnalysisTask): Renamed to '_resultsForTestGroup' * unit-tests/statistics-tests.js: Updated and added unit tests. Canonical link: https://commits.webkit.org/203958@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235255 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-23 23:11:10 +00:00
assert.almostEqual(delta([0.3, 0.06, 0.5], 0.8), 0.2398353, 4);
assert.almostEqual(delta([0.3, 0.06, 0.5], 0.9), 0.3713985, 4);
assert.almostEqual(delta([0.3, 0.06, 0.5], 0.95), 0.5472625, 4);
Add unit tests for config.json and statistics.js https://bugs.webkit.org/show_bug.cgi?id=155626 Reviewed by Darin Adler. Added mocha unit tests for statistics.js and validating config.json. For segmentations, I've extracted real data from our internal perf dashboard. Also fixed some bugs covered by these new tests. * public/shared/statistics.js: (Statistics.movingAverage): Fixed a bug that forwardWindowSize was never used. (Statistics.exponentialMovingAverage): Fixed the bug that the moving average starts at 0. It should start at the first value instead. (.splitIntoSegmentsUntilGoodEnough): Fixed the bug that we may try to segment a time series into more parts than there are data points. Clearly, that doesn't make any sense. (.findOptimalSegmentation): Renamed local variables so that they're more descriptive, and rewrote the debugging code was the old code was emitting some useless data. Also fixed the bug that the length of "segmentation" was off by one (we need segmentCount + 1 elements in the array sine we always include the start of the first segment = 0 and the end of the last segment = values.length). (.SampleVarianceUpperTriangularMatrix): (Statistics): Modernized the export code. * tools/js: Added. * tools/js/config.js: Added. (Config): Added. (Config.prototype.configFilePath): Added. (Config.prototype.value): Added. (Config.prototype.path): Added. * tools/js/database.js: Added. (Database): Added. (Database.prototype.connect): Added. (Database.prototype.disconnect): Added. * unit-tests: Added. * unit-tests/checkconfig.js: Added. Validates config.json. This is useful while setting up a local instance of the perf dashboard. * unit-tests/statistics-tests.js: Added. (assert.almostEqual): Added. Asserts that two floating values are within a given significant digits. (.stdev): (.delta): (.computeWelchsT): Canonical link: https://commits.webkit.org/173743@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198386 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-03-18 07:15:54 +00:00
Show t-test results based on individual measurements to analysis task page. https://bugs.webkit.org/show_bug.cgi?id=188425 Reviewed by Ryosuke Niwa. Added comparison for individual iterations in analysis task page. Added comparison for individual iterations for notification on A/B tests completion. Refactored t-distribution inverse lookup to any degree of freedom with 5 significant figures. * public/shared/statistics.js: Refactored t-distribution inverse lookup function and adapted this change to all invocations. (Statistics.new.this.supportedConfidenceIntervalProbabilities): (Statistics.new.this.supportedOneSideTTestProbabilities): (Statistics.new.this.confidenceIntervalDelta): (Statistics.new.sampleMeanAndVarianceForMultipleSamples): (Statistics.new.this.probabilityRangeForWelchsT): (Statistics.new.this.probabilityRangeForWelchsTFromTwoSampleSets): (Statistics.new.this._determinetwoSidedProbabilityBoundaryForWelchsT): (Statistics.new.this.computeWelchsT): (Statistics.new.this._computeWelchsTFromStatistics): (Statistics.new.this.minimumTForOneSidedProbability): Function that does t-distribution inverse lookup. * public/v3/components/analysis-results-viewer.js: Adapted TestGroup.compareTestResults change. (AnalysisResultsViewer.TestGroupStackingBlock.prototype._measurementsForCommitSet): (AnalysisResultsViewer.TestGroupStackingBlock.prototype._computeTestGroupStatus): (AnalysisResultsViewer.TestGroupStackingBlock.prototype._valuesForCommitSet): Deleted. * public/v3/components/test-group-results-viewer.js: Show both comparisions for both individual and mean. (TestGroupResultsViewer.prototype._renderResultsTable): (TestGroupResultsViewer.prototype._buildRowForMetric.): (TestGroupResultsViewer.prototype._buildValueMap): * public/v3/models/test-group.js: (TestGroup.compareTestResults): Added comparison for individual iterations. * tools/js/test-group-result-page.js: (TestGroupResultPage.prototype._constructTableForMetric): (TestGroupResultPage.prototype.get styleTemplate): (TestGroupResultPage): (TestGroupResultPage.prototype._URLForAnalysisTask): Renamed to '_resultsForTestGroup' * unit-tests/statistics-tests.js: Updated and added unit tests. Canonical link: https://commits.webkit.org/203958@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235255 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-23 23:11:10 +00:00
assert.almostEqual(delta([-0.3, 0.06, 0.5], 0.8), 0.4361900, 4);
assert.almostEqual(delta([-0.3, 0.06, 0.5], 0.9), 0.6754647, 4);
assert.almostEqual(delta([-0.3, 0.06, 0.5], 0.95), 0.9953098, 4);
Add unit tests for config.json and statistics.js https://bugs.webkit.org/show_bug.cgi?id=155626 Reviewed by Darin Adler. Added mocha unit tests for statistics.js and validating config.json. For segmentations, I've extracted real data from our internal perf dashboard. Also fixed some bugs covered by these new tests. * public/shared/statistics.js: (Statistics.movingAverage): Fixed a bug that forwardWindowSize was never used. (Statistics.exponentialMovingAverage): Fixed the bug that the moving average starts at 0. It should start at the first value instead. (.splitIntoSegmentsUntilGoodEnough): Fixed the bug that we may try to segment a time series into more parts than there are data points. Clearly, that doesn't make any sense. (.findOptimalSegmentation): Renamed local variables so that they're more descriptive, and rewrote the debugging code was the old code was emitting some useless data. Also fixed the bug that the length of "segmentation" was off by one (we need segmentCount + 1 elements in the array sine we always include the start of the first segment = 0 and the end of the last segment = values.length). (.SampleVarianceUpperTriangularMatrix): (Statistics): Modernized the export code. * tools/js: Added. * tools/js/config.js: Added. (Config): Added. (Config.prototype.configFilePath): Added. (Config.prototype.value): Added. (Config.prototype.path): Added. * tools/js/database.js: Added. (Database): Added. (Database.prototype.connect): Added. (Database.prototype.disconnect): Added. * unit-tests: Added. * unit-tests/checkconfig.js: Added. Validates config.json. This is useful while setting up a local instance of the perf dashboard. * unit-tests/statistics-tests.js: Added. (assert.almostEqual): Added. Asserts that two floating values are within a given significant digits. (.stdev): (.delta): (.computeWelchsT): Canonical link: https://commits.webkit.org/173743@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198386 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-03-18 07:15:54 +00:00
Show t-test results based on individual measurements to analysis task page. https://bugs.webkit.org/show_bug.cgi?id=188425 Reviewed by Ryosuke Niwa. Added comparison for individual iterations in analysis task page. Added comparison for individual iterations for notification on A/B tests completion. Refactored t-distribution inverse lookup to any degree of freedom with 5 significant figures. * public/shared/statistics.js: Refactored t-distribution inverse lookup function and adapted this change to all invocations. (Statistics.new.this.supportedConfidenceIntervalProbabilities): (Statistics.new.this.supportedOneSideTTestProbabilities): (Statistics.new.this.confidenceIntervalDelta): (Statistics.new.sampleMeanAndVarianceForMultipleSamples): (Statistics.new.this.probabilityRangeForWelchsT): (Statistics.new.this.probabilityRangeForWelchsTFromTwoSampleSets): (Statistics.new.this._determinetwoSidedProbabilityBoundaryForWelchsT): (Statistics.new.this.computeWelchsT): (Statistics.new.this._computeWelchsTFromStatistics): (Statistics.new.this.minimumTForOneSidedProbability): Function that does t-distribution inverse lookup. * public/v3/components/analysis-results-viewer.js: Adapted TestGroup.compareTestResults change. (AnalysisResultsViewer.TestGroupStackingBlock.prototype._measurementsForCommitSet): (AnalysisResultsViewer.TestGroupStackingBlock.prototype._computeTestGroupStatus): (AnalysisResultsViewer.TestGroupStackingBlock.prototype._valuesForCommitSet): Deleted. * public/v3/components/test-group-results-viewer.js: Show both comparisions for both individual and mean. (TestGroupResultsViewer.prototype._renderResultsTable): (TestGroupResultsViewer.prototype._buildRowForMetric.): (TestGroupResultsViewer.prototype._buildValueMap): * public/v3/models/test-group.js: (TestGroup.compareTestResults): Added comparison for individual iterations. * tools/js/test-group-result-page.js: (TestGroupResultPage.prototype._constructTableForMetric): (TestGroupResultPage.prototype.get styleTemplate): (TestGroupResultPage): (TestGroupResultPage.prototype._URLForAnalysisTask): Renamed to '_resultsForTestGroup' * unit-tests/statistics-tests.js: Updated and added unit tests. Canonical link: https://commits.webkit.org/203958@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235255 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-23 23:11:10 +00:00
assert.almostEqual(delta([123, 107, 109, 104, 111], 0.8), 5.001167, 4);
assert.almostEqual(delta([123, 107, 109, 104, 111], 0.9), 6.953874, 4);
assert.almostEqual(delta([123, 107, 109, 104, 111], 0.95), 9.056490, 4);
Add unit tests for config.json and statistics.js https://bugs.webkit.org/show_bug.cgi?id=155626 Reviewed by Darin Adler. Added mocha unit tests for statistics.js and validating config.json. For segmentations, I've extracted real data from our internal perf dashboard. Also fixed some bugs covered by these new tests. * public/shared/statistics.js: (Statistics.movingAverage): Fixed a bug that forwardWindowSize was never used. (Statistics.exponentialMovingAverage): Fixed the bug that the moving average starts at 0. It should start at the first value instead. (.splitIntoSegmentsUntilGoodEnough): Fixed the bug that we may try to segment a time series into more parts than there are data points. Clearly, that doesn't make any sense. (.findOptimalSegmentation): Renamed local variables so that they're more descriptive, and rewrote the debugging code was the old code was emitting some useless data. Also fixed the bug that the length of "segmentation" was off by one (we need segmentCount + 1 elements in the array sine we always include the start of the first segment = 0 and the end of the last segment = values.length). (.SampleVarianceUpperTriangularMatrix): (Statistics): Modernized the export code. * tools/js: Added. * tools/js/config.js: Added. (Config): Added. (Config.prototype.configFilePath): Added. (Config.prototype.value): Added. (Config.prototype.path): Added. * tools/js/database.js: Added. (Database): Added. (Database.prototype.connect): Added. (Database.prototype.disconnect): Added. * unit-tests: Added. * unit-tests/checkconfig.js: Added. Validates config.json. This is useful while setting up a local instance of the perf dashboard. * unit-tests/statistics-tests.js: Added. (assert.almostEqual): Added. Asserts that two floating values are within a given significant digits. (.stdev): (.delta): (.computeWelchsT): Canonical link: https://commits.webkit.org/173743@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198386 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-03-18 07:15:54 +00:00
Show t-test results based on individual measurements to analysis task page. https://bugs.webkit.org/show_bug.cgi?id=188425 Reviewed by Ryosuke Niwa. Added comparison for individual iterations in analysis task page. Added comparison for individual iterations for notification on A/B tests completion. Refactored t-distribution inverse lookup to any degree of freedom with 5 significant figures. * public/shared/statistics.js: Refactored t-distribution inverse lookup function and adapted this change to all invocations. (Statistics.new.this.supportedConfidenceIntervalProbabilities): (Statistics.new.this.supportedOneSideTTestProbabilities): (Statistics.new.this.confidenceIntervalDelta): (Statistics.new.sampleMeanAndVarianceForMultipleSamples): (Statistics.new.this.probabilityRangeForWelchsT): (Statistics.new.this.probabilityRangeForWelchsTFromTwoSampleSets): (Statistics.new.this._determinetwoSidedProbabilityBoundaryForWelchsT): (Statistics.new.this.computeWelchsT): (Statistics.new.this._computeWelchsTFromStatistics): (Statistics.new.this.minimumTForOneSidedProbability): Function that does t-distribution inverse lookup. * public/v3/components/analysis-results-viewer.js: Adapted TestGroup.compareTestResults change. (AnalysisResultsViewer.TestGroupStackingBlock.prototype._measurementsForCommitSet): (AnalysisResultsViewer.TestGroupStackingBlock.prototype._computeTestGroupStatus): (AnalysisResultsViewer.TestGroupStackingBlock.prototype._valuesForCommitSet): Deleted. * public/v3/components/test-group-results-viewer.js: Show both comparisions for both individual and mean. (TestGroupResultsViewer.prototype._renderResultsTable): (TestGroupResultsViewer.prototype._buildRowForMetric.): (TestGroupResultsViewer.prototype._buildValueMap): * public/v3/models/test-group.js: (TestGroup.compareTestResults): Added comparison for individual iterations. * tools/js/test-group-result-page.js: (TestGroupResultPage.prototype._constructTableForMetric): (TestGroupResultPage.prototype.get styleTemplate): (TestGroupResultPage): (TestGroupResultPage.prototype._URLForAnalysisTask): Renamed to '_resultsForTestGroup' * unit-tests/statistics-tests.js: Updated and added unit tests. Canonical link: https://commits.webkit.org/203958@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235255 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-23 23:11:10 +00:00
assert.almostEqual(delta([6785, 7812, 6904, 7503, 6943, 7207, 6812], 0.8), 212.6155, 4);
assert.almostEqual(delta([6785, 7812, 6904, 7503, 6943, 7207, 6812], 0.9), 286.9585, 4);
assert.almostEqual(delta([6785, 7812, 6904, 7503, 6943, 7207, 6812], 0.95), 361.3469, 4);
Add unit tests for config.json and statistics.js https://bugs.webkit.org/show_bug.cgi?id=155626 Reviewed by Darin Adler. Added mocha unit tests for statistics.js and validating config.json. For segmentations, I've extracted real data from our internal perf dashboard. Also fixed some bugs covered by these new tests. * public/shared/statistics.js: (Statistics.movingAverage): Fixed a bug that forwardWindowSize was never used. (Statistics.exponentialMovingAverage): Fixed the bug that the moving average starts at 0. It should start at the first value instead. (.splitIntoSegmentsUntilGoodEnough): Fixed the bug that we may try to segment a time series into more parts than there are data points. Clearly, that doesn't make any sense. (.findOptimalSegmentation): Renamed local variables so that they're more descriptive, and rewrote the debugging code was the old code was emitting some useless data. Also fixed the bug that the length of "segmentation" was off by one (we need segmentCount + 1 elements in the array sine we always include the start of the first segment = 0 and the end of the last segment = values.length). (.SampleVarianceUpperTriangularMatrix): (Statistics): Modernized the export code. * tools/js: Added. * tools/js/config.js: Added. (Config): Added. (Config.prototype.configFilePath): Added. (Config.prototype.value): Added. (Config.prototype.path): Added. * tools/js/database.js: Added. (Database): Added. (Database.prototype.connect): Added. (Database.prototype.disconnect): Added. * unit-tests: Added. * unit-tests/checkconfig.js: Added. Validates config.json. This is useful while setting up a local instance of the perf dashboard. * unit-tests/statistics-tests.js: Added. (assert.almostEqual): Added. Asserts that two floating values are within a given significant digits. (.stdev): (.delta): (.computeWelchsT): Canonical link: https://commits.webkit.org/173743@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198386 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-03-18 07:15:54 +00:00
});
});
// https://en.wikipedia.org/wiki/Welch%27s_t_test
var example1 = {
A1: [27.5, 21.0, 19.0, 23.6, 17.0, 17.9, 16.9, 20.1, 21.9, 22.6, 23.1, 19.6, 19.0, 21.7, 21.4],
A2: [27.1, 22.0, 20.8, 23.4, 23.4, 23.5, 25.8, 22.0, 24.8, 20.2, 21.9, 22.1, 22.9, 20.5, 24.4],
expectedT: 2.46,
expectedDegreesOfFreedom: 25.0,
expectedRange: [0.95, 0.98] // P = 0.021 so 1 - P = 0.979 is between 0.95 and 0.98
};
var example2 = {
A1: [17.2, 20.9, 22.6, 18.1, 21.7, 21.4, 23.5, 24.2, 14.7, 21.8],
A2: [21.5, 22.8, 21.0, 23.0, 21.6, 23.6, 22.5, 20.7, 23.4, 21.8, 20.7, 21.7, 21.5, 22.5, 23.6, 21.5, 22.5, 23.5, 21.5, 21.8],
expectedT: 1.57,
expectedDegreesOfFreedom: 9.9,
expectedRange: [0.8, 0.9] // P = 0.149 so 1 - P = 0.851 is between 0.8 and 0.9
};
var example3 = {
A1: [19.8, 20.4, 19.6, 17.8, 18.5, 18.9, 18.3, 18.9, 19.5, 22.0],
A2: [28.2, 26.6, 20.1, 23.3, 25.2, 22.1, 17.7, 27.6, 20.6, 13.7, 23.2, 17.5, 20.6, 18.0, 23.9, 21.6, 24.3, 20.4, 24.0, 13.2],
expectedT: 2.22,
expectedDegreesOfFreedom: 24.5,
expectedRange: [0.95, 0.98] // P = 0.036 so 1 - P = 0.964 is beteween 0.95 and 0.98
};
describe('computeWelchsT', function () {
function computeWelchsT(values1, values2, probability) {
return Statistics.computeWelchsT(values1, 0, values1.length, values2, 0, values2.length, probability);
}
it('should detect the statistically significant difference using Welch\'s t-test', function () {
assert.equal(computeWelchsT(example1.A1, example1.A2, 0.8).significantlyDifferent, true);
assert.equal(computeWelchsT(example1.A1, example1.A2, 0.9).significantlyDifferent, true);
assert.equal(computeWelchsT(example1.A1, example1.A2, 0.95).significantlyDifferent, true);
assert.equal(computeWelchsT(example1.A1, example1.A2, 0.98).significantlyDifferent, false);
assert.equal(computeWelchsT(example2.A1, example2.A2, 0.8).significantlyDifferent, true);
assert.equal(computeWelchsT(example2.A1, example2.A2, 0.9).significantlyDifferent, false);
assert.equal(computeWelchsT(example2.A1, example2.A2, 0.95).significantlyDifferent, false);
assert.equal(computeWelchsT(example2.A1, example2.A2, 0.98).significantlyDifferent, false);
assert.equal(computeWelchsT(example3.A1, example3.A2, 0.8).significantlyDifferent, true);
assert.equal(computeWelchsT(example3.A1, example3.A2, 0.9).significantlyDifferent, true);
assert.equal(computeWelchsT(example3.A1, example3.A2, 0.95).significantlyDifferent, true);
assert.equal(computeWelchsT(example3.A1, example3.A2, 0.98).significantlyDifferent, false);
});
it('should find the t-value of values using Welch\'s t-test', function () {
assert.almostEqual(computeWelchsT(example1.A1, example1.A2).t, example1.expectedT, 2);
assert.almostEqual(computeWelchsT(example2.A1, example2.A2).t, example2.expectedT, 2);
assert.almostEqual(computeWelchsT(example3.A1, example3.A2).t, example3.expectedT, 2);
});
it('should find the degreees of freedom using WelchSatterthwaite equation', function () {
assert.almostEqual(computeWelchsT(example1.A1, example1.A2).degreesOfFreedom, example1.expectedDegreesOfFreedom, 2);
assert.almostEqual(computeWelchsT(example2.A1, example2.A2).degreesOfFreedom, example2.expectedDegreesOfFreedom, 2);
assert.almostEqual(computeWelchsT(example3.A1, example3.A2).degreesOfFreedom, example3.expectedDegreesOfFreedom, 2);
});
it('should respect the start and the end indices', function () {
var A1 = example2.A1.slice();
var A2 = example2.A2.slice();
var expectedT = Statistics.computeWelchsT(A1, 0, A1.length, A2, 0, A2.length).t;
A1.unshift(21);
A1.push(15);
A1.push(24);
assert.almostEqual(Statistics.computeWelchsT(A1, 1, A1.length - 3, A2, 0, A2.length).t, expectedT);
A2.unshift(24.3);
A2.unshift(25.8);
A2.push(23);
A2.push(24);
A2 = A2.reverse();
assert.almostEqual(Statistics.computeWelchsT(A1, 1, A1.length - 3, A2, 2, A2.length - 4).t, expectedT);
});
});
describe('probabilityRangeForWelchsT', function () {
it('should find the t-value of values using Welch\'s t-test', function () {
assert.almostEqual(Statistics.probabilityRangeForWelchsT(example1.A1, example1.A2).t, example1.expectedT, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsT(example2.A1, example2.A2).t, example2.expectedT, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsT(example3.A1, example3.A2).t, example3.expectedT, 2);
});
it('should find the degreees of freedom using WelchSatterthwaite equation', function () {
assert.almostEqual(Statistics.probabilityRangeForWelchsT(example1.A1, example1.A2).degreesOfFreedom,
example1.expectedDegreesOfFreedom, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsT(example2.A1, example2.A2).degreesOfFreedom,
example2.expectedDegreesOfFreedom, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsT(example3.A1, example3.A2).degreesOfFreedom,
example3.expectedDegreesOfFreedom, 2);
});
it('should compute the range of probabilites using the p-value of Welch\'s t-test', function () {
assert.almostEqual(Statistics.probabilityRangeForWelchsT(example1.A1, example1.A2).range[0], example1.expectedRange[0]);
assert.almostEqual(Statistics.probabilityRangeForWelchsT(example1.A1, example1.A2).range[1], example1.expectedRange[1]);
assert.almostEqual(Statistics.probabilityRangeForWelchsT(example2.A1, example2.A2).range[0], example2.expectedRange[0]);
assert.almostEqual(Statistics.probabilityRangeForWelchsT(example2.A1, example2.A2).range[1], example2.expectedRange[1]);
assert.almostEqual(Statistics.probabilityRangeForWelchsT(example3.A1, example3.A2).range[0], example3.expectedRange[0]);
assert.almostEqual(Statistics.probabilityRangeForWelchsT(example3.A1, example3.A2).range[1], example3.expectedRange[1]);
});
});
Show t-test results based on individual measurements to analysis task page. https://bugs.webkit.org/show_bug.cgi?id=188425 Reviewed by Ryosuke Niwa. Added comparison for individual iterations in analysis task page. Added comparison for individual iterations for notification on A/B tests completion. Refactored t-distribution inverse lookup to any degree of freedom with 5 significant figures. * public/shared/statistics.js: Refactored t-distribution inverse lookup function and adapted this change to all invocations. (Statistics.new.this.supportedConfidenceIntervalProbabilities): (Statistics.new.this.supportedOneSideTTestProbabilities): (Statistics.new.this.confidenceIntervalDelta): (Statistics.new.sampleMeanAndVarianceForMultipleSamples): (Statistics.new.this.probabilityRangeForWelchsT): (Statistics.new.this.probabilityRangeForWelchsTFromTwoSampleSets): (Statistics.new.this._determinetwoSidedProbabilityBoundaryForWelchsT): (Statistics.new.this.computeWelchsT): (Statistics.new.this._computeWelchsTFromStatistics): (Statistics.new.this.minimumTForOneSidedProbability): Function that does t-distribution inverse lookup. * public/v3/components/analysis-results-viewer.js: Adapted TestGroup.compareTestResults change. (AnalysisResultsViewer.TestGroupStackingBlock.prototype._measurementsForCommitSet): (AnalysisResultsViewer.TestGroupStackingBlock.prototype._computeTestGroupStatus): (AnalysisResultsViewer.TestGroupStackingBlock.prototype._valuesForCommitSet): Deleted. * public/v3/components/test-group-results-viewer.js: Show both comparisions for both individual and mean. (TestGroupResultsViewer.prototype._renderResultsTable): (TestGroupResultsViewer.prototype._buildRowForMetric.): (TestGroupResultsViewer.prototype._buildValueMap): * public/v3/models/test-group.js: (TestGroup.compareTestResults): Added comparison for individual iterations. * tools/js/test-group-result-page.js: (TestGroupResultPage.prototype._constructTableForMetric): (TestGroupResultPage.prototype.get styleTemplate): (TestGroupResultPage): (TestGroupResultPage.prototype._URLForAnalysisTask): Renamed to '_resultsForTestGroup' * unit-tests/statistics-tests.js: Updated and added unit tests. Canonical link: https://commits.webkit.org/203958@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235255 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-08-23 23:11:10 +00:00
describe('minimumTForOneSidedProbability', () => {
it('should not infinite loop when lookup t-value for any degrees of freedom', () => {
for(const probability of [0.9, 0.95, 0.975, 0.99]) {
for (let degreesOfFreedom = 1; degreesOfFreedom < 100000; degreesOfFreedom += 1)
Statistics.minimumTForOneSidedProbability(probability, degreesOfFreedom);
}
})
});
describe('probabilityRangeForWelchsTForMultipleSamples', () => {
function splitSample(samples) {
const mid = samples.length / 2;
return splitSampleByIndices(samples, mid);
}
function splitSampleByIndices(samples, ...indices) {
const sampleSize = samples.length;
const splittedSamples = [];
let previousIndex = 0;
for (const index of indices) {
if (index == previousIndex)
continue;
console.assert(index > previousIndex);
console.assert(index <= sampleSize);
splittedSamples.push(samples.slice(previousIndex, index));
previousIndex = index;
}
if (previousIndex < sampleSize)
splittedSamples.push(samples.slice(previousIndex, sampleSize));
return splittedSamples.map((values) => ({sum: Statistics.sum(values), squareSum: Statistics.squareSum(values), sampleSize: values.length}));
}
it('should find the t-value of values using Welch\'s t-test', () => {
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSample(example1.A1), splitSample(example1.A2)).t, example1.expectedT, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSample(example2.A1), splitSample(example2.A2)).t, example2.expectedT, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSample(example3.A1), splitSample(example3.A2)).t, example3.expectedT, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example1.A1, 1), splitSampleByIndices(example1.A2, 1)).t, example1.expectedT, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example2.A1, 1), splitSampleByIndices(example2.A2, 1)).t, example2.expectedT, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example3.A1, 1), splitSampleByIndices(example3.A2, 1)).t, example3.expectedT, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example1.A1, 0), splitSampleByIndices(example1.A2, 0)).t, example1.expectedT, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example2.A1, 0), splitSampleByIndices(example2.A2, 0)).t, example2.expectedT, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example3.A1, 0), splitSampleByIndices(example3.A2, 0)).t, example3.expectedT, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example1.A1, 1, 4), splitSampleByIndices(example1.A2, 1, 4)).t, example1.expectedT, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example2.A1, 1, 4), splitSampleByIndices(example2.A2, 1, 4)).t, example2.expectedT, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example3.A1, 1, 4), splitSampleByIndices(example3.A2, 1, 4)).t, example3.expectedT, 2);
});
it('should find the degreees of freedom using WelchSatterthwaite equation when split evenly', () => {
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSample(example1.A1), splitSample(example1.A2)).degreesOfFreedom,
example1.expectedDegreesOfFreedom, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSample(example2.A1), splitSample(example2.A2)).degreesOfFreedom,
example2.expectedDegreesOfFreedom, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSample(example3.A1), splitSample(example3.A2)).degreesOfFreedom,
example3.expectedDegreesOfFreedom, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example1.A1, 1), splitSampleByIndices(example1.A2, 1)).degreesOfFreedom,
example1.expectedDegreesOfFreedom, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example2.A1, 1), splitSampleByIndices(example2.A2, 1)).degreesOfFreedom,
example2.expectedDegreesOfFreedom, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example3.A1, 1), splitSampleByIndices(example3.A2, 1)).degreesOfFreedom,
example3.expectedDegreesOfFreedom, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example1.A1, 0), splitSampleByIndices(example1.A2, 0)).degreesOfFreedom,
example1.expectedDegreesOfFreedom, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example2.A1, 0), splitSampleByIndices(example2.A2, 0)).degreesOfFreedom,
example2.expectedDegreesOfFreedom, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example3.A1, 0), splitSampleByIndices(example3.A2, 0)).degreesOfFreedom,
example3.expectedDegreesOfFreedom, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example1.A1, 1, 4), splitSampleByIndices(example1.A2, 1, 4)).degreesOfFreedom,
example1.expectedDegreesOfFreedom, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example2.A1, 1, 4), splitSampleByIndices(example2.A2, 1, 4)).degreesOfFreedom,
example2.expectedDegreesOfFreedom, 2);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example3.A1, 1, 4), splitSampleByIndices(example3.A2, 1, 4)).degreesOfFreedom,
example3.expectedDegreesOfFreedom, 2);
});
it('should compute the range of probabilites using the p-value of Welch\'s t-test when split evenly', function () {
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSample(example1.A1), splitSample(example1.A2)).range[0], example1.expectedRange[0]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSample(example1.A1), splitSample(example1.A2)).range[1], example1.expectedRange[1]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSample(example2.A1), splitSample(example2.A2)).range[0], example2.expectedRange[0]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSample(example2.A1), splitSample(example2.A2)).range[1], example2.expectedRange[1]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSample(example3.A1), splitSample(example3.A2)).range[0], example3.expectedRange[0]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSample(example3.A1), splitSample(example3.A2)).range[1], example3.expectedRange[1]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example1.A1, 1), splitSampleByIndices(example1.A2, 1)).range[0], example1.expectedRange[0]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example1.A1, 1), splitSampleByIndices(example1.A2, 1)).range[1], example1.expectedRange[1]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example2.A1, 1), splitSampleByIndices(example2.A2, 1)).range[0], example2.expectedRange[0]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example2.A1, 1), splitSampleByIndices(example2.A2, 1)).range[1], example2.expectedRange[1]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example3.A1, 1), splitSampleByIndices(example3.A2, 1)).range[0], example3.expectedRange[0]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example3.A1, 1), splitSampleByIndices(example3.A2, 1)).range[1], example3.expectedRange[1]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example1.A1, 0), splitSampleByIndices(example1.A2, 0)).range[0], example1.expectedRange[0]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example1.A1, 0), splitSampleByIndices(example1.A2, 0)).range[1], example1.expectedRange[1]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example2.A1, 0), splitSampleByIndices(example2.A2, 0)).range[0], example2.expectedRange[0]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example2.A1, 0), splitSampleByIndices(example2.A2, 0)).range[1], example2.expectedRange[1]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example3.A1, 0), splitSampleByIndices(example3.A2, 0)).range[0], example3.expectedRange[0]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example3.A1, 0), splitSampleByIndices(example3.A2, 0)).range[1], example3.expectedRange[1]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example1.A1, 1, 4), splitSampleByIndices(example1.A2, 1, 4)).range[0], example1.expectedRange[0]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example1.A1, 1, 4), splitSampleByIndices(example1.A2, 1, 4)).range[1], example1.expectedRange[1]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example2.A1, 1, 4), splitSampleByIndices(example2.A2, 1, 4)).range[0], example2.expectedRange[0]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example2.A1, 1, 4), splitSampleByIndices(example2.A2, 1, 4)).range[1], example2.expectedRange[1]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example3.A1, 1, 4), splitSampleByIndices(example3.A2, 1, 4)).range[0], example3.expectedRange[0]);
assert.almostEqual(Statistics.probabilityRangeForWelchsTForMultipleSamples(splitSampleByIndices(example3.A1, 1, 4), splitSampleByIndices(example3.A2, 1, 4)).range[1], example3.expectedRange[1]);
});
});
Add unit tests for config.json and statistics.js https://bugs.webkit.org/show_bug.cgi?id=155626 Reviewed by Darin Adler. Added mocha unit tests for statistics.js and validating config.json. For segmentations, I've extracted real data from our internal perf dashboard. Also fixed some bugs covered by these new tests. * public/shared/statistics.js: (Statistics.movingAverage): Fixed a bug that forwardWindowSize was never used. (Statistics.exponentialMovingAverage): Fixed the bug that the moving average starts at 0. It should start at the first value instead. (.splitIntoSegmentsUntilGoodEnough): Fixed the bug that we may try to segment a time series into more parts than there are data points. Clearly, that doesn't make any sense. (.findOptimalSegmentation): Renamed local variables so that they're more descriptive, and rewrote the debugging code was the old code was emitting some useless data. Also fixed the bug that the length of "segmentation" was off by one (we need segmentCount + 1 elements in the array sine we always include the start of the first segment = 0 and the end of the last segment = values.length). (.SampleVarianceUpperTriangularMatrix): (Statistics): Modernized the export code. * tools/js: Added. * tools/js/config.js: Added. (Config): Added. (Config.prototype.configFilePath): Added. (Config.prototype.value): Added. (Config.prototype.path): Added. * tools/js/database.js: Added. (Database): Added. (Database.prototype.connect): Added. (Database.prototype.disconnect): Added. * unit-tests: Added. * unit-tests/checkconfig.js: Added. Validates config.json. This is useful while setting up a local instance of the perf dashboard. * unit-tests/statistics-tests.js: Added. (assert.almostEqual): Added. Asserts that two floating values are within a given significant digits. (.stdev): (.delta): (.computeWelchsT): Canonical link: https://commits.webkit.org/173743@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198386 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-03-18 07:15:54 +00:00
describe('movingAverage', function () {
it('should return the origian values when both forward and backward window size is 0', function () {
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 0, 0), [1, 2, 3, 4, 5]);
});
it('should find the moving average with a positive backward window', function () {
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 1, 0),
[1, (1 + 2) / 2, (2 + 3) / 2, (3 + 4) / 2, (4 + 5) / 2]);
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 2, 0),
[1, (1 + 2) / 2, (1 + 2 + 3) / 3, (2 + 3 + 4) / 3, (3 + 4 + 5) / 3]);
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 3, 0),
[1, (1 + 2) / 2, (1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (2 + 3 + 4 + 5) / 4]);
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 4, 0),
[1, (1 + 2) / 2, (1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (1 + 2 + 3 + 4 + 5) / 5]);
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 5, 0),
[1, (1 + 2) / 2, (1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (1 + 2 + 3 + 4 + 5) / 5]);
});
it('should find the moving average with a positive forward window', function () {
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 0, 1),
[(1 + 2) / 2, (2 + 3) / 2, (3 + 4) / 2, (4 + 5) / 2, 5]);
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 0, 2),
[(1 + 2 + 3) / 3, (2 + 3 + 4) / 3, (3 + 4 + 5) / 3, (4 + 5) / 2, 5]);
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 0, 3),
[(1 + 2 + 3 + 4) / 4, (2 + 3 + 4 + 5) / 4, (3 + 4 + 5) / 3, (4 + 5) / 2, 5]);
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 0, 4),
[(1 + 2 + 3 + 4 + 5) / 5, (2 + 3 + 4 + 5) / 4, (3 + 4 + 5) / 3, (4 + 5) / 2, 5]);
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 0, 5),
[(1 + 2 + 3 + 4 + 5) / 5, (2 + 3 + 4 + 5) / 4, (3 + 4 + 5) / 3, (4 + 5) / 2, 5]);
});
it('should find the moving average when both backward and forward window sizes are specified', function () {
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 1, 1),
[(1 + 2) / 2, (1 + 2 + 3) / 3, (2 + 3 + 4) / 3, (3 + 4 + 5) / 3, (4 + 5) / 2]);
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 1, 2),
[(1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (2 + 3 + 4 + 5) / 4, (3 + 4 + 5) / 3, (4 + 5) / 2]);
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 2, 1),
[(1 + 2) / 2, (1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (2 + 3 + 4 + 5) / 4, (3 + 4 + 5) / 3]);
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 2, 2),
[(1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (1 + 2 + 3 + 4 + 5) / 5, (2 + 3 + 4 + 5) / 4, (3 + 4 + 5) / 3]);
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 2, 3),
[(1 + 2 + 3 + 4) / 4, (1 + 2 + 3 + 4 + 5) / 5, (1 + 2 + 3 + 4 + 5) / 5, (2 + 3 + 4 + 5) / 4, (3 + 4 + 5) / 3]);
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 3, 2),
[(1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (1 + 2 + 3 + 4 + 5) / 5, (1 + 2 + 3 + 4 + 5) / 5, (2 + 3 + 4 + 5) / 4]);
assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 3, 3),
[(1 + 2 + 3 + 4) / 4, (1 + 2 + 3 + 4 + 5) / 5, (1 + 2 + 3 + 4 + 5) / 5, (1 + 2 + 3 + 4 + 5) / 5, (2 + 3 + 4 + 5) / 4]);
});
});
describe('cumulativeMovingAverage', function () {
it('should find the cumulative moving average', function () {
assert.deepEqual(Statistics.cumulativeMovingAverage([1, 2, 3, 4, 5]),
[1, (1 + 2) / 2, (1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (1 + 2 + 3 + 4 + 5) / 5]);
assert.deepEqual(Statistics.cumulativeMovingAverage([-1, 7, 0, 8.5, 2]),
[-1, (-1 + 7) / 2, (-1 + 7 + 0) / 3, (-1 + 7 + 0 + 8.5) / 4, (-1 + 7 + 0 + 8.5 + 2) / 5]);
});
});
describe('exponentialMovingAverage', function () {
it('should find the exponential moving average', function () {
var averages = Statistics.exponentialMovingAverage([1, 2, 3, 4, 5], 0.2);
assert.equal(averages[0], 1);
assert.almostEqual(averages[1], 0.2 * 2 + 0.8 * averages[0]);
assert.almostEqual(averages[2], 0.2 * 3 + 0.8 * averages[1]);
assert.almostEqual(averages[3], 0.2 * 4 + 0.8 * averages[2]);
assert.almostEqual(averages[4], 0.2 * 5 + 0.8 * averages[3]);
averages = Statistics.exponentialMovingAverage([0.8, -0.2, 0.4, -0.3, 0.5], 0.1);
assert.almostEqual(averages[0], 0.8);
assert.almostEqual(averages[1], 0.1 * -0.2 + 0.9 * averages[0]);
assert.almostEqual(averages[2], 0.1 * 0.4 + 0.9 * averages[1]);
assert.almostEqual(averages[3], 0.1 * -0.3 + 0.9 * averages[2]);
assert.almostEqual(averages[4], 0.1 * 0.5 + 0.9 * averages[3]);
});
});
describe('segmentTimeSeriesGreedyWithStudentsTTest', function () {
it('should segment time series', function () {
assert.deepEqual(Statistics.segmentTimeSeriesGreedyWithStudentsTTest([1, 1, 1, 3, 3, 3], 1), [0, 2, 6]);
assert.deepEqual(Statistics.segmentTimeSeriesGreedyWithStudentsTTest([1, 1.2, 0.9, 1.1, 1.5, 1.7, 1.8], 1), [0, 4, 7]);
});
});
describe('segmentTimeSeriesByMaximizingSchwarzCriterion', function () {
it('should segment time series of length 0 into a single segment', function () {
var values = [];
assert.deepEqual(Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion(values), [0, 0]);
});
Add unit tests for config.json and statistics.js https://bugs.webkit.org/show_bug.cgi?id=155626 Reviewed by Darin Adler. Added mocha unit tests for statistics.js and validating config.json. For segmentations, I've extracted real data from our internal perf dashboard. Also fixed some bugs covered by these new tests. * public/shared/statistics.js: (Statistics.movingAverage): Fixed a bug that forwardWindowSize was never used. (Statistics.exponentialMovingAverage): Fixed the bug that the moving average starts at 0. It should start at the first value instead. (.splitIntoSegmentsUntilGoodEnough): Fixed the bug that we may try to segment a time series into more parts than there are data points. Clearly, that doesn't make any sense. (.findOptimalSegmentation): Renamed local variables so that they're more descriptive, and rewrote the debugging code was the old code was emitting some useless data. Also fixed the bug that the length of "segmentation" was off by one (we need segmentCount + 1 elements in the array sine we always include the start of the first segment = 0 and the end of the last segment = values.length). (.SampleVarianceUpperTriangularMatrix): (Statistics): Modernized the export code. * tools/js: Added. * tools/js/config.js: Added. (Config): Added. (Config.prototype.configFilePath): Added. (Config.prototype.value): Added. (Config.prototype.path): Added. * tools/js/database.js: Added. (Database): Added. (Database.prototype.connect): Added. (Database.prototype.disconnect): Added. * unit-tests: Added. * unit-tests/checkconfig.js: Added. Validates config.json. This is useful while setting up a local instance of the perf dashboard. * unit-tests/statistics-tests.js: Added. (assert.almostEqual): Added. Asserts that two floating values are within a given significant digits. (.stdev): (.delta): (.computeWelchsT): Canonical link: https://commits.webkit.org/173743@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198386 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-03-18 07:15:54 +00:00
it('should not segment time series of length two into two pieces', function () {
var values = [1, 2];
assert.deepEqual(Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion(values), [0, 2]);
});
it('should segment time series [1, 2, 3] into three pieces', function () {
var values = [1, 2, 3];
assert.deepEqual(Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion(values), [0, 1, 3]);
});
it('should segment time series for platform=47 metric=4875 between 1453938553772 and 1454630903100 into two parts', function () {
var values = [
1546.5603, 1548.1536, 1563.5452, 1539.7823, 1546.4184, 1548.9299, 1532.5444, 1546.2800, 1547.1760, 1551.3507,
1548.3277, 1544.7673, 1542.7157, 1538.1700, 1538.0948, 1543.0364, 1537.9737, 1542.2611, 1543.9685, 1546.4901,
1544.4080, 1540.8671, 1537.3353, 1549.4331, 1541.4436, 1544.1299, 1550.1770, 1553.1872, 1549.3417, 1542.3788,
1543.5094, 1541.7905, 1537.6625, 1547.3840, 1538.5185, 1549.6764, 1556.6138, 1552.0476, 1541.7629, 1544.7006,
/* segments changes here */
1587.1390, 1594.5451, 1586.2430, 1596.7310, 1548.1423];
assert.deepEqual(Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion(values), [0, 39, values.length]);
});
it('should segment time series for platform=51 metric=4565 betweeen 1452191332230 and 1454628206453 into two parts', function () {
var values = [
147243216, 147736350, 146670090, 146629723, 142749220, 148234161, 147303822, 145112097, 145852468, 147094741,
147568897, 145160531, 148028242, 141272279, 144323236, 147492567, 146219156, 144895726, 144418925, 145455873,
141924694, 141025833, 142082139, 144154698, 145312939, 148282554, 151852126, 149303740, 149431703, 150300257,
148752468, 150449779, 150030118, 150553542, 151775421, 146666762, 149492535, 147143284, 150356837, 147799616,
149889520,
258634751, 147397840, 256106147, 261100534, 255903392, 259658019, 259501433, 257685682, 258460322, 255563633,
259050663, 255567490, 253274911];
assert.deepEqual(Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion(values), [0, 40, values.length]);
});
it('should not segment time series for platform=51 metric=4817 betweeen 1453926047749 and 1454635479052 into multiple parts', function () {
var values = [
5761.3, 5729.4, 5733.49, 5727.4, 5726.56, 5727.48, 5716.79, 5721.23, 5682.5, 5735.71,
5750.99, 5755.51, 5756.02, 5725.76, 5710.14, 5776.17, 5774.29, 5769.99, 5739.65, 5756.05,
5722.87, 5726.8, 5779.23, 5772.2, 5763.1, 5807.05];
assert.deepEqual(Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion(values), [0, values.length]);
});
it('should not segment time series for platform=51 metric=4817 betweeen 1453926047749 and 1454635479052 into multiple parts', function () {
var values = new Array(37);
for (let i = 0; i < 37; i++)
values[i] = 1;
assert.deepEqual(Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion(values), [ 0, 6, 16, 26, 37 ]);
});
Add unit tests for config.json and statistics.js https://bugs.webkit.org/show_bug.cgi?id=155626 Reviewed by Darin Adler. Added mocha unit tests for statistics.js and validating config.json. For segmentations, I've extracted real data from our internal perf dashboard. Also fixed some bugs covered by these new tests. * public/shared/statistics.js: (Statistics.movingAverage): Fixed a bug that forwardWindowSize was never used. (Statistics.exponentialMovingAverage): Fixed the bug that the moving average starts at 0. It should start at the first value instead. (.splitIntoSegmentsUntilGoodEnough): Fixed the bug that we may try to segment a time series into more parts than there are data points. Clearly, that doesn't make any sense. (.findOptimalSegmentation): Renamed local variables so that they're more descriptive, and rewrote the debugging code was the old code was emitting some useless data. Also fixed the bug that the length of "segmentation" was off by one (we need segmentCount + 1 elements in the array sine we always include the start of the first segment = 0 and the end of the last segment = values.length). (.SampleVarianceUpperTriangularMatrix): (Statistics): Modernized the export code. * tools/js: Added. * tools/js/config.js: Added. (Config): Added. (Config.prototype.configFilePath): Added. (Config.prototype.value): Added. (Config.prototype.path): Added. * tools/js/database.js: Added. (Database): Added. (Database.prototype.connect): Added. (Database.prototype.disconnect): Added. * unit-tests: Added. * unit-tests/checkconfig.js: Added. Validates config.json. This is useful while setting up a local instance of the perf dashboard. * unit-tests/statistics-tests.js: Added. (assert.almostEqual): Added. Asserts that two floating values are within a given significant digits. (.stdev): (.delta): (.computeWelchsT): Canonical link: https://commits.webkit.org/173743@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198386 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-03-18 07:15:54 +00:00
});
Added UI to show potential regressions in chart with t-testing against segmentations. https://bugs.webkit.org/show_bug.cgi?id=184131 Reviewed by Ryosuke Niwa. Added UI in the chart-pane so that user can use new option in trendline which not only shows the segmentation, but also t-test against potential changes indicated by segmentation. Fix a bug in AnalysisTaskPage that chart is not updated when change type of task changes. * public/shared/statistics.js: Added a function to t-test certain range based on segmentation results. (Statistics.supportedOneSideTTestProbabilities): (Statistics.findRangesForChangeDetectionsWithWelchsTTest): The argument `segmentations`, every 2 items in the list defines segmentation, that is why the index incremental is 2 in this funcion. * public/v3/components/chart-pane-base.js: Will select the range if user clicks on a suggested annotation. (ChartPaneBase.prototype.configure): (ChartPaneBase.prototype._didClickAnnotation): * public/v3/components/chart-styles.js: (ChartStyles.annotationFillStyleForTask): Added 'annotationFillStyleForTask' to determine the fillStyle for annotation based on change type of a analysis task. * public/v3/components/interactive-time-series-chart.js: (InteractiveTimeSeriesChart.prototype._findAnnotation): Also need to search among suggested annotaions. * public/v3/components/time-series-chart.js: Introduced 'suggested annotaion' which does not have an existing task and is suggested by t-test based on segmentation. (TimeSeriesChart): (TimeSeriesChart.prototype.setSuggestedAnnotations): (TimeSeriesChart.prototype.allAnnotations): Returns both annotations with and without analysis task. (TimeSeriesChart.prototype._layoutAnnotationBars): Should take all annotations in the calculation. * public/v3/models/measurement-set.js: (MeasurementSet.prototype.metricId): Returns metric id. * public/v3/models/metric.js: (Metric.prototype.summarizeForValues): Added helper function to summarize a given value * public/v3/models/test-group.js: (TestGroup.prototype.compareTestResults): Adapted to use 'Metric.summarizeForValues'. * public/v3/pages/chart-pane.js: Added 'Segmentation with t-test analysis' to 'ChartTrendLineTypes'. (ChartPane.prototype._renderTrendLinePopover): (ChartPane.prototype.async._updateTrendLine): make it an async function. * unit-tests/statistics-tests.js: Added unit tests for 'findRangesForChangeDetectionsWithWelchsTTest'. Canonical link: https://commits.webkit.org/199881@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230295 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-04-05 04:49:21 +00:00
describe('findRangesForChangeDetectionsWithWelchsTTest', () => {
it('should return an empty array if the value is empty list', () => {
assert.deepEqual(Statistics.findRangesForChangeDetectionsWithWelchsTTest([], [], 0.975), []);
});
it('should return an empty array if segmentation is empty list', () => {
assert.deepEqual(Statistics.findRangesForChangeDetectionsWithWelchsTTest([1,2,3], [], 0.975), []);
});
it('should return the range if computeWelchsT shows a significant change', () => {
const values = [
747.30337423744,
731.47392585276,
743.66763513161,
738.02055323487,
738.25426340842,
742.38680046471,
733.13921703284,
739.22069966147,
735.69295749633,
743.01705472504,
745.45778145306,
731.04841157169,
729.4372674973,
735.4497416527,
739.0230668644,
730.91782989909,
722.18725411279,
731.96223451728,
730.04119216192,
730.78087646284,
729.63155210365,
730.17585200878,
733.93766054706,
740.74920717197,
752.14718023647,
764.49990164847,
766.36100828473,
756.2291883252,
750.14522451097,
749.57595092266,
748.03624881866,
769.41522176386,
744.04660430456,
751.17927808265,
753.29996854062,
757.01813756936,
746.62413820741,
742.64420062736,
758.12726352772,
778.2278439089,
775.11818554541,
775.11818554541];
const segmentation = [{
seriesIndex: 0,
time: 1505176030671,
value: 736.5366704896555,
x: 370.4571789404566,
y: 185.52613334520248,
},
{
seriesIndex: 18,
time: 1515074391534,
value: 736.5366704896555,
x: 919.4183852714947,
y: 185.52613334520248
},
{
seriesIndex: 18,
time: 1515074391534,
value: 750.3483428383142,
x: 919.4183852714947,
y: 177.9710953409673,
},
{
seriesIndex: 41,
time: 1553851695869,
value: 750.3483428383142,
x: 3070.000290764446,
y: 177.9710953409673,
}];
assert.deepEqual(Statistics.findRangesForChangeDetectionsWithWelchsTTest(values, segmentation, 0.975), [
{
"endIndex": 29,
"segmentationEndValue": 750.3483428383142,
"segmentationStartValue": 736.5366704896555,
"startIndex": 6
}
]);
})
});
Add unit tests for config.json and statistics.js https://bugs.webkit.org/show_bug.cgi?id=155626 Reviewed by Darin Adler. Added mocha unit tests for statistics.js and validating config.json. For segmentations, I've extracted real data from our internal perf dashboard. Also fixed some bugs covered by these new tests. * public/shared/statistics.js: (Statistics.movingAverage): Fixed a bug that forwardWindowSize was never used. (Statistics.exponentialMovingAverage): Fixed the bug that the moving average starts at 0. It should start at the first value instead. (.splitIntoSegmentsUntilGoodEnough): Fixed the bug that we may try to segment a time series into more parts than there are data points. Clearly, that doesn't make any sense. (.findOptimalSegmentation): Renamed local variables so that they're more descriptive, and rewrote the debugging code was the old code was emitting some useless data. Also fixed the bug that the length of "segmentation" was off by one (we need segmentCount + 1 elements in the array sine we always include the start of the first segment = 0 and the end of the last segment = values.length). (.SampleVarianceUpperTriangularMatrix): (Statistics): Modernized the export code. * tools/js: Added. * tools/js/config.js: Added. (Config): Added. (Config.prototype.configFilePath): Added. (Config.prototype.value): Added. (Config.prototype.path): Added. * tools/js/database.js: Added. (Database): Added. (Database.prototype.connect): Added. (Database.prototype.disconnect): Added. * unit-tests: Added. * unit-tests/checkconfig.js: Added. Validates config.json. This is useful while setting up a local instance of the perf dashboard. * unit-tests/statistics-tests.js: Added. (assert.almostEqual): Added. Asserts that two floating values are within a given significant digits. (.stdev): (.delta): (.computeWelchsT): Canonical link: https://commits.webkit.org/173743@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198386 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-03-18 07:15:54 +00:00
});