Author Topic: Performance Stopwatch (Superseded)  (Read 5036 times)

Exergist

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 405
  • Ride the lightning
Performance Stopwatch (Superseded)
« on: June 26, 2018, 10:56:52 AM »
UPDATE: This methodology was superseded by Performance Stopwatch v2.



Pfeil has already shared a method for creating a fairly comprehensive stopwatch. Below you will find a simple stopwatch for tracking the speed of your commands, which is useful for optimization. It basically involves an inline function that leverages the .NET Stopwatch class as well as a VA action for setting a boolean variable that triggers the stopwatch to stop and output the elapsed time (seconds).

VoiceAttack Command
Code: [Select]
// Start the stopwatch and wait for ~~StopwatchTrigger
Inline C# Function: Stopwatch

// Place your VA command actions here

// Activate the StopWatchTrigger for stopping the stopwatch and reporting the elapsed time
Set Boolean [~~StopwatchTrigger] to True

Inline Function
Referenced Assemblies: System.dll
Code: [Select]
using System.Diagnostics;
using System.Threading;

public class VAInline
{
public void main()
{
Stopwatch sw = new Stopwatch(); // Create new Stopwatch instance
sw.Start(); // Start the stopwatch
while (VA.GetBoolean("~~StopwatchTrigger") == null) // Loop while the VoiceAttack boolean variable ~~StopwatchTrigger is NOT SET (null)
{
if (VA.Stopped == true) // Check if a "Stop All Commands" action was executed
{
Thread.Sleep(100); // Brief pause for better ordering of event log output
VA.ResetStopFlag(); // Reset the flag for the "Stop All Commands" action
VA.SetBoolean("StopwatchRunning", null); // Reset VoiceAttack boolean variable
VA.WriteToLog("Stopwatch terminated", "red"); // Output info to event log
return; // Return from inline function
}
}
sw.Stop(); // Stop the stopwatch
VA.WriteToLog("Elapsed Time [s] = " + sw.Elapsed.Seconds + "." + sw.Elapsed.Milliseconds, "blue"); // Output info to VoiceAttack event log
}
}



EDIT: added code to inline function for handling "Stop All Commands" action. Though personally I think the below method is cleaner and more easily implemented.
« Last Edit: January 04, 2019, 03:02:23 PM by Exergist »

Exergist

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 405
  • Ride the lightning
Re: Performance Stopwatch
« Reply #1 on: June 26, 2018, 02:30:04 PM »
Here's another approach (arguably simpler). It involves a separate command that is called whenever you want to start or stop the stopwatch (stopping also results in the elapsed time being displayed). This method also allows you to call the Stopwatch command "by name."

Here is the Stopwatch command:
Code: [Select]
// Check if the stopwatch is NOT running
Begin Boolean Compare : [StopwatchRunning] Equals False (Evaluate 'Not Set' as false)
    // Start the stopwatch, wait for additional input, and subsequently output elapsed time (seconds)
    Inline C# Function: Stopwatch
Else
    // Reset the StopwatchRunning boolean flag
    Set Boolean [StopwatchRunning] to [Not Set]
End Condition

...and here's the inline function:
Referenced Assemblies: System.dll
Code: [Select]
using System.Diagnostics;
using System.Threading;

public class VAInline
{
public void main()
{
Stopwatch sw = new Stopwatch(); // Create new Stopwatch instance
sw.Start(); // Start the stopwatch
VA.SetBoolean("StopwatchRunning", true); // Set the VoiceAttack boolean flag indicating that the stopwatch is running
while (VA.GetBoolean("StopwatchRunning") == true) // Loop while the VoiceAttack boolean variable StopwatchRunning is TRUE
{
if (VA.Stopped == true) // Check if a "Stop All Commands" action was executed
{
Thread.Sleep(100); // Brief pause for better ordering of event log output
                                sw.Stop(); // Stop the stopwatch
VA.ResetStopFlag(); // Reset the flag for the "Stop All Commands" action
VA.SetBoolean("StopwatchRunning", null); // Reset VoiceAttack boolean variable
VA.WriteToLog("Stopwatch terminated", "blue"); // Output info to event log
return; // Return from inline function
}
}
sw.Stop(); // Stop the stopwatch
VA.WriteToLog("Elapsed Time [s] = " + (sw.Elapsed.Seconds + sw.Elapsed.Milliseconds/1000.0), "blue"); // Output info to VoiceAttack event log
}
}

Then simply use the Stopwatch command in your command like this:
Code: [Select]
// Execute Stopwatch command. First call starts the stopwatch.
Execute command, 'Stopwatch' (and wait until it completes)

// Your VA command actions go here

// Execute Stopwatch command. Second call stops the stopwatch and outputs the elapsed time.
Execute command, 'Stopwatch' (and wait until it completes)

If a "Stop All Commands" action is executed while the stopwatch is running the function will clean up and terminate accordingly.

Note that due to the way the inline function is set up the VoiceAttack boolean variable must be globally scoped (not command or profile scoped). The Stopwatch command cleans up the variable after the stopwatch is stopped, so you shouldn't need to worry about it.

EDIT: fixed a calculation error and added code to terminate the stopwatch if VA.Stopped == true
« Last Edit: January 04, 2019, 02:45:12 PM by Exergist »