Add support for timing steps and pipelines#613
Add support for timing steps and pipelines#613SamCarlberg merged 43 commits intoWPIRoboticsProjects:masterfrom
Conversation
| private Pane aboutPane; | ||
| @FXML | ||
| private StatusBar statusBar; | ||
| private Label elapsedTimeLabel; // TODO improve the layout of this label |
There was a problem hiding this comment.
This label isn't centered vertically in the status bar, and it separates the start/stop button from the "Pipeline STATE" text.
There was a problem hiding this comment.
I would move the Pipeline status into its own label and then center both (i.e. do not use statusBar.setText() for the status)
|
It may also be a good idea to collect the timing data and have a UI for displaying statistics about each operation, such as
And statistics about the pipeline
So for the pipeline pictured in the top comment,
|
Current coverage is 54.25% (diff: 51.56%)@@ master #613 diff @@
==========================================
Files 209 218 +9
Lines 6713 7067 +354
Methods 0 0
Messages 0 0
Branches 656 697 +41
==========================================
+ Hits 3657 3834 +177
- Misses 2886 3062 +176
- Partials 170 171 +1
|
|
Can you maybe put those stats in the right side of the status bar? |
|
I think it makes more sense on the left side, that stuff is all related and it makes sense to keep them together. It's also not great for UX to put it on the right side |
| @FXML | ||
| private Labeled title; | ||
| @FXML | ||
| private Label elapsedTime; |
There was a problem hiding this comment.
You can fix it in the fxml with padding
| // >1: error | ||
| private static final double alpha = 0.35; | ||
|
|
||
| private final ExponentialMovingAverage ema = new ExponentialMovingAverage(alpha); |
There was a problem hiding this comment.
Maybe change this to a normal arithmetic moving average, the output of this still isn't very consistent.
|
When I open the analysis window I get a stack overflow: pastebin Looks like it happens when I click and drag the window. |
|
Does it only happen when you move the window? |
|
That looks like a JavaFX bug to me |
| checkNotNull(data, "data"); | ||
| this.source = source; | ||
| this.elapsedTime = elapsedTime; | ||
| this.data = data; |
There was a problem hiding this comment.
checkNotNull(source, "source"); returns the source so you can just use it in the same line as the assignment.
I think I'll make it CSV in a TextArea to make it easy to import into stuff like excel and google sheets |
Fixed an issue with steps not being in their proper order in the analysis
JLLeitschuh
left a comment
There was a problem hiding this comment.
The places that I'm not totally clear what's going on could use some inline documentation.
I'd rather avoid using instanceof if possible. Can you try to avoid that.
| * @param o2 the second step to compare | ||
| */ | ||
| @Override | ||
| default int compare(Step o1, Step o2) { |
| started(); | ||
| target.run(); | ||
| } finally { | ||
| stopped(); |
There was a problem hiding this comment.
Do you want to catch any potential exceptions this may throw?
There was a problem hiding this comment.
No, exceptions are propagated up the stack and are caught.
| * @throws IllegalStateException if this a call to this method is not preceded by a call to | ||
| * {@link #started()}. | ||
| */ | ||
| public synchronized void stopped() { |
There was a problem hiding this comment.
Should this be renamed stop?
Its an action, stopped infers a question.
| analysisStage.setOnCloseRequest(event -> eventBus.post(BenchmarkEvent.finished())); | ||
| eventBus.register(controller); | ||
| analysisStage.showAndWait(); | ||
| eventBus.unregister(controller); // unregister to avoid memory leak |
There was a problem hiding this comment.
How does this work on a high DPI screen?
The fonts get all weird on those sort of screens.
| sb.append(stddev.get(i)); | ||
| sb.append('\n'); | ||
| } | ||
| return sb.toString(); |
There was a problem hiding this comment.
Are you sure this is correctly formatted CSV?
This isn't using a library to create CSV and there aren't any tests for this code.
There was a problem hiding this comment.
I have a plugin from codecov that shows me in the PR what code is covered and what isn't.
This isn't covered by tests.
https://chrome.google.com/webstore/detail/codecov-extension/keefkhehidemnokodkdkejapdgfjmijf/related
| } | ||
|
|
||
| @Subscribe | ||
| @SuppressWarnings("PMD.UnusedPrivateMethod") |
There was a problem hiding this comment.
There must be a way to disable this error when there is this annotation on the method.
Not sure how to do it.
| final String formatStyle = "-fx-accent: hsb(%.2f, 100%%, 100%%);"; | ||
| progressBar.setStyle(String.format(formatStyle, h)); | ||
| } else { | ||
| progressBar.setStyle("-fx-accent: hsb(180, 100%, 75%);"); // blue-gray |
There was a problem hiding this comment.
Want to use css classes to do this?
| table.setItems(tableItems); | ||
|
|
||
| benchmarkRunsField.textProperty().addListener((observable, oldValue, newValue) -> { | ||
| if ((oldValue.isEmpty() && "0".equals(newValue)) || !newValue.matches("[\\d]*")) { |
There was a problem hiding this comment.
What is this regex checking?
There was a problem hiding this comment.
Checks if the input is a number
| @Subscribe | ||
| @SuppressWarnings({"PMD.UnusedPrivateMethod", "PMD.UnusedFormalParameter"}) | ||
| private void runStopped(TimerEvent event) { | ||
| if (!(event.getTarget() instanceof PipelineRunner)) { |
There was a problem hiding this comment.
instanceof is bad practice. What are you trying to do here?
Can you do something different here?
| @Subscribe | ||
| @SuppressWarnings("PMD.UnusedPrivateMethod") | ||
| private void onRun(TimerEvent event) { | ||
| if (event.getTarget() instanceof Step) { |
There was a problem hiding this comment.
Can you avoid this instance of check?
There was a problem hiding this comment.
Why do you need to do this instanceof check?
| /** | ||
| * Gets the number of samples. | ||
| */ | ||
| public int getN() { |
There was a problem hiding this comment.
Can this be something like sampleCount or number or dataPoints? getN seems ambiguous.
JLLeitschuh
left a comment
There was a problem hiding this comment.
Just a few things.
Also, can you do something other than that instanceof check?
| private final int n; | ||
| private final double sum; | ||
| private final double mean; | ||
| private final double s; |
There was a problem hiding this comment.
Can you rename this to something like sqrt?
There was a problem hiding this comment.
It's the standard deviation, s is a standard symbol
| * </code></pre> | ||
| * </p> | ||
| */ | ||
| public class Timer { |
| * @param value the value to calculate the hotness of | ||
| * @return the hotness of the given value. | ||
| */ | ||
| public double hotness(double value) { |
There was a problem hiding this comment.
What is the range of hotness values? 0-10? 0 to 1? This should be documented.
There was a problem hiding this comment.
Hotness can be any number >= 0. The current implementation is just the number of standard deviations above the mean
There was a problem hiding this comment.
How do you represent hotness on the UI? What is the scale? What is the max value of the UI?
There was a problem hiding this comment.
Hotness is represented by the hue of the bar. The length of the bar represents what percentage of time the step takes. Hotness values over three standard deviations are clamped to avoid having high-sigma steps having the same color as low-sigma steps.
There was a problem hiding this comment.
Can you document that a little bit better in the javadoc?
Imagine I don't understand statistics and want to use this class. :p
f7776c9 to
3d9f2b6
Compare
Conflicts: ui/src/main/java/edu/wpi/grip/ui/MainWindowController.java
This lets users know which parts of their pipelines take the most time, and how long the pipeline takes as a whole.