2020-12-26 14:12:05 -08:00
|
|
|
// Copyright (c) FIRST and other WPILib contributors.
|
|
|
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
|
|
|
// the WPILib BSD license file in the root directory of this project.
|
2020-04-02 06:09:40 +03:00
|
|
|
|
2025-11-07 19:55:43 -05:00
|
|
|
package org.wpilib.system;
|
2020-04-02 06:09:40 +03:00
|
|
|
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.function.Consumer;
|
|
|
|
|
|
|
|
|
|
/**
|
2020-12-29 22:45:16 -08:00
|
|
|
* A class for keeping track of how much time it takes for different parts of code to execute. This
|
|
|
|
|
* is done with epochs, that are added by calls to {@link #addEpoch(String)}, and can be printed
|
|
|
|
|
* with a call to {@link #printEpochs()}.
|
2020-04-02 06:09:40 +03:00
|
|
|
*
|
2020-12-29 22:45:16 -08:00
|
|
|
* <p>Epochs are a way to partition the time elapsed so that when overruns occur, one can determine
|
|
|
|
|
* which parts of an operation consumed the most time.
|
2020-04-02 06:09:40 +03:00
|
|
|
*/
|
|
|
|
|
public class Tracer {
|
|
|
|
|
private static final long kMinPrintPeriod = 1000000; // microseconds
|
|
|
|
|
|
|
|
|
|
private long m_lastEpochsPrintTime; // microseconds
|
|
|
|
|
private long m_startTime; // microseconds
|
|
|
|
|
|
|
|
|
|
private final Map<String, Long> m_epochs = new HashMap<>(); // microseconds
|
|
|
|
|
|
2020-12-29 22:45:16 -08:00
|
|
|
/** Tracer constructor. */
|
2020-04-02 06:09:40 +03:00
|
|
|
public Tracer() {
|
|
|
|
|
resetTimer();
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-29 22:45:16 -08:00
|
|
|
/** Clears all epochs. */
|
2020-04-02 06:09:40 +03:00
|
|
|
public void clearEpochs() {
|
|
|
|
|
m_epochs.clear();
|
|
|
|
|
resetTimer();
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-29 22:45:16 -08:00
|
|
|
/** Restarts the epoch timer. */
|
2023-12-09 21:45:02 -08:00
|
|
|
public final void resetTimer() {
|
2020-04-02 06:09:40 +03:00
|
|
|
m_startTime = RobotController.getFPGATime();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Adds time since last epoch to the list printed by printEpochs().
|
|
|
|
|
*
|
|
|
|
|
* <p>Epochs are a way to partition the time elapsed so that when overruns occur, one can
|
|
|
|
|
* determine which parts of an operation consumed the most time.
|
|
|
|
|
*
|
2020-12-29 22:45:16 -08:00
|
|
|
* <p>This should be called immediately after execution has finished, with a call to this method
|
|
|
|
|
* or {@link #resetTimer()} before execution.
|
2020-04-02 06:09:40 +03:00
|
|
|
*
|
|
|
|
|
* @param epochName The name to associate with the epoch.
|
|
|
|
|
*/
|
|
|
|
|
public void addEpoch(String epochName) {
|
|
|
|
|
long currentTime = RobotController.getFPGATime();
|
|
|
|
|
m_epochs.put(epochName, currentTime - m_startTime);
|
|
|
|
|
m_startTime = currentTime;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-29 22:45:16 -08:00
|
|
|
/** Prints list of epochs added so far and their times to the DriverStation. */
|
2020-04-02 06:09:40 +03:00
|
|
|
public void printEpochs() {
|
|
|
|
|
printEpochs(out -> DriverStation.reportWarning(out, false));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Prints list of epochs added so far and their times to the entered String consumer.
|
|
|
|
|
*
|
|
|
|
|
* <p>This overload can be useful for logging to a file, etc.
|
|
|
|
|
*
|
|
|
|
|
* @param output the stream that the output is sent to
|
|
|
|
|
*/
|
|
|
|
|
public void printEpochs(Consumer<String> output) {
|
|
|
|
|
long now = RobotController.getFPGATime();
|
2020-04-05 23:09:21 -07:00
|
|
|
if (now - m_lastEpochsPrintTime > kMinPrintPeriod) {
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
2020-04-02 06:09:40 +03:00
|
|
|
m_lastEpochsPrintTime = now;
|
2020-12-29 22:45:16 -08:00
|
|
|
m_epochs.forEach(
|
2023-12-03 16:21:32 -08:00
|
|
|
(key, value) -> sb.append(String.format("\t%s: %.6fs\n", key, value / 1.0e6)));
|
2020-04-05 23:09:21 -07:00
|
|
|
if (sb.length() > 0) {
|
|
|
|
|
output.accept(sb.toString());
|
|
|
|
|
}
|
2020-04-02 06:09:40 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|