-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for timing steps and pipelines #613
Add support for timing steps and pipelines #613
Conversation
@@ -59,6 +66,7 @@ | |||
private Pane aboutPane; | |||
@FXML | |||
private StatusBar statusBar; | |||
private Label elapsedTimeLabel; // TODO improve the layout of this label |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
@@ -46,6 +53,8 @@ | |||
@FXML | |||
private Labeled title; | |||
@FXML | |||
private Label elapsedTime; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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? |
Here is another log and a video: |
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
checkNotNull(source, "source");
returns the source so you can just use it in the same line as the assignment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is cleaner IMO
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting solution.
started(); | ||
target.run(); | ||
} finally { | ||
stopped(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want to catch any potential exceptions this may throw?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
@@ -192,6 +206,25 @@ private void moveStepRight() { | |||
pipeline.moveStep(step, +1); | |||
} | |||
|
|||
@Subscribe | |||
@SuppressWarnings("PMD.UnusedPrivateMethod") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this regex checking?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you avoid this instance of check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need to do this instanceof check?
/** | ||
* Gets the number of samples. | ||
*/ | ||
public int getN() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be something like sampleCount
or number
or dataPoints
? getN
seems ambiguous.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you rename this to something like sqrt
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the standard deviation, s
is a standard symbol
* </code></pre> | ||
* </p> | ||
*/ | ||
public class Timer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Annotate with @ThreadSafe
?
* @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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the range of hotness values? 0-10? 0 to 1? This should be documented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.