diff --git a/core/src/main/java/edu/wpi/grip/core/metrics/Analysis.java b/core/src/main/java/edu/wpi/grip/core/metrics/Analysis.java deleted file mode 100644 index 9986ee8f14..0000000000 --- a/core/src/main/java/edu/wpi/grip/core/metrics/Analysis.java +++ /dev/null @@ -1,80 +0,0 @@ -package edu.wpi.grip.core.metrics; - -import com.google.common.base.MoreObjects; - -import java.util.Collection; -import java.util.stream.DoubleStream; - -import javax.annotation.concurrent.Immutable; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Analysis data of a timed action. Contains - * - */ -@Immutable -public final class Analysis { - - private final double average; - private final Statistics statistics; - - /** - * Class-private constructor. Use {@link #of(double...)} or {@link #of(Collection)} - * factory methods. - */ - private Analysis(double average, Statistics statistics) { - this.average = average; - this.statistics = statistics; - } - - /** - * Analyzes the given values. - * - * @param values the values to analyze - * @return an analysis of the given values - */ - public static Analysis of(double... values) { - checkNotNull(values, "values"); - double average = DoubleStream.of(values).average().orElse(0); - Statistics statistics = Statistics.of(values); - return new Analysis(average, statistics); - } - - /** - * Analyzes the given collection of values. - * - * @param values the values to analyze - * @return an analysis of the given values - */ - public static Analysis of(Collection values) { - checkNotNull(values, "values"); - return of(values.stream().mapToDouble(Number::doubleValue).toArray()); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("average", average) - .add("statistics", statistics) - .toString(); - } - - /** - * Gets the average running time of the step this data is for. - */ - public double getAverage() { - return average; - } - - /** - * Gets the statistical analysis of the data. - */ - public Statistics getStatistics() { - return statistics; - } - -} diff --git a/core/src/main/java/edu/wpi/grip/core/metrics/Statistics.java b/core/src/main/java/edu/wpi/grip/core/metrics/Statistics.java index d1cfee6fe5..7e033f2ede 100644 --- a/core/src/main/java/edu/wpi/grip/core/metrics/Statistics.java +++ b/core/src/main/java/edu/wpi/grip/core/metrics/Statistics.java @@ -2,6 +2,8 @@ import com.google.common.base.MoreObjects; +import java.util.Collection; + import javax.annotation.concurrent.Immutable; import static com.google.common.base.Preconditions.checkNotNull; @@ -9,18 +11,19 @@ /** * Statistics analysis. Contains: * */ @Immutable public final class Statistics { - private final int n; + private final int numSamples; private final double sum; private final double mean; - private final double s; + private final double standardDeviation; /** * "null" statistics with every value set to zero. @@ -49,27 +52,38 @@ public static Statistics of(double... samples) { return new Statistics(n, sum, mean, s); } - private Statistics(int n, double sum, double mean, double s) { - this.n = n; + /** + * Calculates the statistics of the given samples. + * + * @param samples the samples to analyze + * @return a statistical analysis of the given samples + */ + public static Statistics of(Collection samples) { + checkNotNull(samples); + return of(samples.stream().mapToDouble(Number::doubleValue).toArray()); + } + + private Statistics(int numSamples, double sum, double mean, double standardDeviation) { + this.numSamples = numSamples; this.sum = sum; this.mean = mean; - this.s = s; + this.standardDeviation = standardDeviation; } @Override public String toString() { return MoreObjects.toStringHelper(this) - .add("n", n) + .add("numSamples", numSamples) .add("mean", mean) - .add("s", s) + .add("standardDeviation", standardDeviation) .toString(); } /** * Gets the number of samples. */ - public int getN() { - return n; + public int getNumSamples() { + return numSamples; } /** @@ -90,7 +104,7 @@ public double getMean() { * Gets the standard deviation in the samples. */ public double getStandardDeviation() { - return s; + return standardDeviation; } /** @@ -105,7 +119,7 @@ public double getStandardDeviation() { * @return the hotness of the given value. */ public double hotness(double value) { - if (n < 2) { + if (numSamples < 2) { // Hotness doesn't make sense if there's 0 or 1 data points return 0; } @@ -113,7 +127,7 @@ public double hotness(double value) { // Avoid negative hotness return 0; } - return (value - mean) / s; + return (value - mean) / standardDeviation; } } diff --git a/core/src/test/java/edu/wpi/grip/core/metrics/AnalysisTest.java b/core/src/test/java/edu/wpi/grip/core/metrics/AnalysisTest.java deleted file mode 100644 index e3cad89bc4..0000000000 --- a/core/src/test/java/edu/wpi/grip/core/metrics/AnalysisTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package edu.wpi.grip.core.metrics; - -import org.junit.Test; - -import java.util.Arrays; -import java.util.Collection; - -import static org.junit.Assert.assertEquals; - -public class AnalysisTest { - - @Test - public void testArrayConstructor() { - double[] values = {1, 2, 3, 4, 5}; - Analysis a = Analysis.of(values); - assertEquals("Average should be 3", 3, a.getAverage(), 0); - Statistics statistics = a.getStatistics(); - assertEquals("n should be 5", 5, statistics.getN(), 0); - assertEquals("sum should be 15", 15, statistics.getSum(), 0); - assertEquals("mean should be 3", 3, statistics.getMean(), 0); - assertEquals("std dev should be sqrt(2)", Math.sqrt(2), statistics.getStandardDeviation(), 0); - assertEquals("hotness should be 0", statistics.hotness(1), 0, 0); - assertEquals("hotness should be 0", statistics.hotness(2), 0, 0); - assertEquals("hotness should be 0", statistics.hotness(3), 0, 0); - assertEquals("hotness should be 1/sqrt(2)", statistics.hotness(4), 1 / Math.sqrt(2), 0); - assertEquals("hotness should be 2/sqrt(2)", statistics.hotness(5), 2 / Math.sqrt(2), 0); - } - - @Test - public void testCollectionConstructor() { - Collection values = Arrays.asList(1, 2, 3, 4, 5); - Analysis a = Analysis.of(values); - assertEquals("Average should be 3", 3, a.getAverage(), 0); - Statistics statistics = a.getStatistics(); - assertEquals("n should be 5", 5, statistics.getN(), 0); - assertEquals("sum should be 15", 15, statistics.getSum(), 0); - assertEquals("mean should be 3", 3, statistics.getMean(), 0); - assertEquals("std dev should be sqrt(2)", Math.sqrt(2), statistics.getStandardDeviation(), 0); - assertEquals("hotness should be 0", statistics.hotness(1), 0, 0); - assertEquals("hotness should be 0", statistics.hotness(2), 0, 0); - assertEquals("hotness should be 0", statistics.hotness(3), 0, 0); - assertEquals("hotness should be 1/sqrt(2)", statistics.hotness(4), 1 / Math.sqrt(2), 0); - assertEquals("hotness should be 2/sqrt(2)", statistics.hotness(5), 2 / Math.sqrt(2), 0); - } - -} diff --git a/core/src/test/java/edu/wpi/grip/core/metrics/StatisticsTest.java b/core/src/test/java/edu/wpi/grip/core/metrics/StatisticsTest.java index 50ac86ee37..46a72a1bb9 100644 --- a/core/src/test/java/edu/wpi/grip/core/metrics/StatisticsTest.java +++ b/core/src/test/java/edu/wpi/grip/core/metrics/StatisticsTest.java @@ -9,7 +9,7 @@ public class StatisticsTest { @Test public void testNil() { Statistics statistics = Statistics.NIL; - assertEquals("n should be 0", 0, statistics.getN(), 0); + assertEquals("n should be 0", 0, statistics.getNumSamples(), 0); assertEquals("sum should be 0", 0, statistics.getSum(), 0); assertEquals("mean should be 0", 0, statistics.getMean(), 0); assertEquals("std dev should be 0", 0, statistics.getStandardDeviation(), 0); @@ -20,7 +20,7 @@ public void testNil() { public void testEmpty() { double[] values = {}; Statistics statistics = Statistics.of(values); - assertEquals("n should be 0", 0, statistics.getN(), 0); + assertEquals("n should be 0", 0, statistics.getNumSamples(), 0); assertEquals("sum should be 0", 0, statistics.getSum(), 0); assertEquals("mean should be 0", 0, statistics.getMean(), 0); assertEquals("std dev should be 0", 0, statistics.getStandardDeviation(), 0); @@ -31,7 +31,7 @@ public void testEmpty() { public void testSingleDataPoint() { double[] values = {Math.PI}; Statistics statistics = Statistics.of(values); - assertEquals("n should be 1", 1, statistics.getN(), 0); + assertEquals("n should be 1", 1, statistics.getNumSamples(), 0); assertEquals("sum should be pi", Math.PI, statistics.getSum(), 0); assertEquals("mean should be pi", Math.PI, statistics.getMean(), 0); assertEquals("std dev should be 0", 0, statistics.getStandardDeviation(), 0); @@ -42,7 +42,7 @@ public void testSingleDataPoint() { public void testMultipleDataPoints() { double[] values = {1, 2, 3, 4, 5}; Statistics statistics = Statistics.of(values); - assertEquals("n should be 5", 5, statistics.getN(), 0); + assertEquals("n should be 5", 5, statistics.getNumSamples(), 0); assertEquals("sum should be 15", 15, statistics.getSum(), 0); assertEquals("mean should be 3", 3, statistics.getMean(), 0); assertEquals("std dev should be sqrt(2)", Math.sqrt(2), statistics.getStandardDeviation(), 0); diff --git a/ui/src/main/java/edu/wpi/grip/ui/analysis/AnalysisWindowController.java b/ui/src/main/java/edu/wpi/grip/ui/analysis/AnalysisWindowController.java index 09f75d4a44..553b8bb589 100644 --- a/ui/src/main/java/edu/wpi/grip/ui/analysis/AnalysisWindowController.java +++ b/ui/src/main/java/edu/wpi/grip/ui/analysis/AnalysisWindowController.java @@ -6,10 +6,9 @@ import edu.wpi.grip.core.events.BenchmarkEvent; import edu.wpi.grip.core.events.RunStoppedEvent; import edu.wpi.grip.core.events.TimerEvent; -import edu.wpi.grip.core.metrics.Analysis; +import edu.wpi.grip.core.metrics.Statistics; import edu.wpi.grip.core.metrics.BenchmarkRunner; import edu.wpi.grip.core.metrics.CsvExporter; -import edu.wpi.grip.core.metrics.Statistics; import com.google.common.collect.EvictingQueue; import com.google.common.eventbus.Subscribe; @@ -54,11 +53,11 @@ public class AnalysisWindowController { // Table @FXML - private TableView table; + private TableView table; @FXML - private TableColumn operationColumn; + private TableColumn operationColumn; @FXML - private TableColumn timeColumn; + private TableColumn timeColumn; // Benchmarking @FXML @@ -67,9 +66,9 @@ public class AnalysisWindowController { private TextField benchmarkRunsField; private BenchmarkRunner benchmarker; - private final Callback extractor = + private final Callback extractor = entry -> new Observable[] {entry.stepProperty(), entry.analysisProperty()}; - private final ObservableList tableItems + private final ObservableList tableItems = FXCollections.observableArrayList(extractor); private StepIndexer stepIndexer = null; @@ -92,17 +91,17 @@ public void initialize() { operationColumn.setCellValueFactory( e -> new SimpleStringProperty(e.getValue().getStep().getOperationDescription().name())); timeColumn.setCellValueFactory(e -> e.getValue().analysisProperty()); - timeColumn.setCellFactory(col -> new TableCell() { + timeColumn.setCellFactory(col -> new TableCell() { @Override - protected void updateItem(Analysis analysis, boolean empty) { - if (analysis == null || empty) { + protected void updateItem(Statistics statistics, boolean empty) { + if (statistics == null || empty) { setGraphic(null); } else { Step step = tableItems.get(this.getIndex()).getStep(); TimeView view = timeViewMap.computeIfAbsent(step, s -> new TimeView()); - view.update(analysis.getAverage(), - analysis.getAverage() / lastStats.getSum(), - lastStats.hotness(analysis.getAverage())); + view.update(statistics.getMean(), + statistics.getMean() / lastStats.getSum(), + lastStats.hotness(statistics.getMean())); setGraphic(null); setGraphic(view); } @@ -124,18 +123,18 @@ protected void updateItem(Analysis analysis, boolean empty) { private void onRun(TimerEvent event) { if (event.getTarget() instanceof Step) { Step source = (Step) event.getTarget(); - Optional possibleEntry + Optional possibleEntry = tableItems.stream().filter(e -> e.getStep() == source).findAny(); Collection samples = sampleMap.computeIfAbsent(source, s -> EvictingQueue.create(numRecentSamples)); samples.add(event.getElapsedTime()); - Analysis stepAnalysis = Analysis.of(samples); + Statistics stepStatistics = Statistics.of(samples); if (possibleEntry.isPresent()) { - possibleEntry.get().setAnalysis(stepAnalysis); + possibleEntry.get().setStatistics(stepStatistics); } else { - StepAnalysisEntry entry = new StepAnalysisEntry(); + StepStatisticsEntry entry = new StepStatisticsEntry(); entry.setStep(source); - entry.setAnalysis(stepAnalysis); + entry.setStatistics(stepStatistics); tableItems.add(entry); } } @@ -149,9 +148,9 @@ private void onPipelineFinish(@Nullable RunStoppedEvent event) { .map(Map.Entry::getValue) .mapToDouble(s -> s.parallelStream().mapToLong(Long::longValue).average().orElse(0)) .toArray(); - Analysis analysis = Analysis.of(averageRunTimes); + Statistics statistics = Statistics.of(averageRunTimes); // Update the stats after the pipeline finishes - lastStats = analysis.getStatistics(); + lastStats = statistics; } @Subscribe @@ -274,10 +273,10 @@ private String createReport() { } - private static class StepAnalysisEntry { + private static class StepStatisticsEntry { private final Property stepProperty = new SimpleObjectProperty<>(); - private final Property analysisProperty = new SimpleObjectProperty<>(); + private final Property analysisProperty = new SimpleObjectProperty<>(); public Property stepProperty() { return stepProperty; @@ -291,15 +290,15 @@ public void setStep(Step step) { stepProperty.setValue(step); } - public Property analysisProperty() { + public Property analysisProperty() { return analysisProperty; } - public Analysis getAnalysis() { + public Statistics getStatistics() { return analysisProperty.getValue(); } - public void setAnalysis(Analysis analysis) { + public void setStatistics(Statistics analysis) { analysisProperty.setValue(analysis); }