How to easily time a block of C# code? - c#

I need a simple way (and compact if possible) to execute a block of C# while counting time. Something similar to this C++ code:
elapsed = time_call([&]
{
for_each (a.begin(), a.end(), [&](int n) {
results1.push_back(make_tuple(n, fibonacci(n)));
});
});
where time_call is:
// Calls the provided work function and returns the number of milliseconds
// that it takes to call that function.
template <class Function>
__int64 time_call(Function&& f)
{
__int64 begin = GetTickCount();
f();
return GetTickCount() - begin;
}
I know the stopwatch way... anything more compact ?

TimeSpan TimeAction(Action blockingAction)
{
Stopwatch stopWatch = System.Diagnostics.Stopwatch.StartNew();
blockingAction();
stopWatch.Stop();
return stopWatch.Elapsed;
}
Usage:
var elapsed = TimeAction(() =>
{
//Code to time
});
Based on your sample code (and usage of GetTickCount) you might want to return ElapsedTicks instead of Elapsed.

public double TimeCall(Action actionToExecute)
{
double elapsed = 0;
if (actionToExecute != null)
{
var stopwatch = Stopwatch.StartNew();
actionToExecute.Invoke();
elapsed = stopwatch.ElapsedMilliseconds;
}
return elapsed;
}
How-to use:
var elapsed = TimeCall( () => { foreach( ... ) } );

I don't know the stopwatch way, but C# has lambdas too, so it should be easy enough to implement something similar to time_call().

Related

Unit Test : Custom Timer Assert

I would like to make a custom Assertion for my unit test which would measure the execution time of two c# functions and compare them.
I have written the code below, but there is a better way ?
public static class AssertExtensions
{
public static void MoreSlowThan(Action slowFunction, Action fastFunction)
{
var watch = Stopwatch.StartNew();
slowFunction();
watch.Stop();
var watchBis = Stopwatch.StartNew();
fastFunction();
watchBis.Stop();
Assert.IsTrue(watch.ElapsedMilliseconds >= watchBis.ElapsedMilliseconds);
}
}
called by :
AssertExtensions.MoreSlowThan(() => MyFunction(), () => MyCachedFunction());
(the goal is to compare the execution time of a function with the execution time of the same function in cache)
The best way i found it's refactor it with MSTest-2 like :
public static void IsFaster(this Assert assert, Action expectedFastAction, Action actualSlowAction)
{
var slowStopwatch = Stopwatch.StartNew();
actualSlowAction();
slowStopwatch.Stop();
var fastStopwatch = Stopwatch.StartNew();
expectedFastAction();
fastStopwatch.Stop();
Assert.IsTrue(slowStopwatch.Elapsed >= fastStopwatch.Elapsed, string.Format("First function would be faster than the second. Fast function elapsed time : {0}. Slow function elapsed time : {1}", fastStopwatch.Elapsed, slowStopwatch.Elapsed));
}
And call it with :
Assert.That.IsSlower(() => MyCachedFunction(), () => MyFunction());
If anyone has a better way

Time measurement of functions with different signature in C#

I want to measure the time that certain function calls take in my application. For this I use the Stopwatch class and it works fine. It looks something like this:
static readonly Stopwatch StopWatch = new Stopwatch();
StopWatch.Restart();
void func();
StopWatch.Stop();
Assert.Blabla
However I am typing this around a lot of functions. Is there a way to make a function that does this for me? I tried but since the signatures of the functions are all different I can't figure it out. I took a look at Func and Action, but they seem to require a fixed signature. I would like something like this:
CallAndMeasureFunction(func)
You can use something like below:
Define a method which takes your actual methods delegate as input:
public static TimeSpan GetTimestampFor(Action action)
{
TimeSpan timestamp = new TimeSpan(0);
Stopwatch stopWatch = new Stopwatch();
if (action != null)
{
stopWatch.Start();
action.Invoke();
stopWatch.Stop();
timestamp = stopWatch.Elapsed;
}
return timestamp;
}
and call it as below:
var timeSpan = GetTimestampFor(() => {var xyz = ActualMethodForWhichTimeHasTobeMeasured()});
With this code, you can measure every method's execution time

C#/.NET Timers and the Win32 Sleep function are both inexact

For the following code:
The actual interval is always 1014.01 ms rather than 1000 ms ...
I've also tried to use System.Windows.Forms.Timer, System.Threading.Timer and the WinAPI Sleep(int) function in C++, but the additional increase of 14.01 ms always exists.
The System Clock of Windows 8 is exact, but both the .NET timers and the Sleep(int) function of Windows API are inexact.
public partial class Form1 : Form
{
private long ticks;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
System.Timers.Timer timer = new System.Timers.Timer(1000);
// The actual interval is always 1014.01 ms ...
// I've also tried to use System.Windows.Forms.Timer, System.Threading.Timer
// and the WinAPI Sleep(int) function in C++, but the additional increase
// of 14.01 ms always exists.
timer.Elapsed += timer_Elapsed;
timer.Start();
ticks = System.DateTime.Now.Ticks;
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
textBox1.Text = Math.Round((e.SignalTime.Ticks - ticks) / 10000.0, 2).ToString();
ticks = e.SignalTime.Ticks;
}
}
Update:
The native Sleep function (ReactOS):
// Call SleepEx with bAlertable = FALSE
VOID WINAPI Kernel32.Sleep(IN DWORD dwMilliseconds)
// Call NtDelayExecution with Alertable = bAlertable
// and DelayInterval.QuadPart = dwMilliseconds * -10,000
DWORD WINAPI Kernel32.SleepEx(IN DWORD dwMilliseconds, IN BOOL bAlertable)
// The syscall stub - call the kernel mode function NtDelayExecution directly
NTSTATUS NTAPI Ntdll.NtDelayExecution(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval)
// Check for the access permissions of DelayInterval and then call KeDelayExecutionThread
NTSYSCALLAPI NTSTATUS NTAPI Ntoskrnl.NtDelayExecution(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval)
// Core implement of the sleep/delay function
NTKERNELAPI NTSTATUS NTAPI Ntoskrnl.KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable,
IN PLARGE_INTEGER Interval OPTIONAL)
{
PKTIMER Timer;
PKWAIT_BLOCK TimerBlock;
PKTHREAD Thread = KeGetCurrentThread();
NTSTATUS WaitStatus;
BOOLEAN Swappable;
PLARGE_INTEGER OriginalDueTime;
LARGE_INTEGER DueTime, NewDueTime, InterruptTime;
ULONG Hand = 0;
/* If this is a user-mode wait of 0 seconds, yield execution */
if (!(Interval->QuadPart) && (WaitMode != KernelMode))
{
/* Make sure the wait isn't alertable or interrupting an APC */
if (!(Alertable) && !(Thread->ApcState.UserApcPending))
{
/* Yield execution */
NtYieldExecution();
}
}
/* Setup the original time and timer/wait blocks */
OriginalDueTime = Interval;
Timer = &Thread->Timer;
TimerBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK];
/* Check if the lock is already held */
if (!Thread->WaitNext) goto WaitStart;
/* Otherwise, we already have the lock, so initialize the wait */
Thread->WaitNext = FALSE;
KxDelayThreadWait();
/* Start wait loop */
for (;;)
{
/* Disable pre-emption */
Thread->Preempted = FALSE;
/* Check if a kernel APC is pending and we're below APC_LEVEL */
if ((Thread->ApcState.KernelApcPending) && !(Thread->SpecialApcDisable) &&
(Thread->WaitIrql < APC_LEVEL))
{
/* Unlock the dispatcher */
KiReleaseDispatcherLock(Thread->WaitIrql);
}
else
{
/* Check if we have to bail out due to an alerted state */
WaitStatus = KiCheckAlertability(Thread, Alertable, WaitMode);
if (WaitStatus != STATUS_WAIT_0) break;
/* Check if the timer expired */
InterruptTime.QuadPart = KeQueryInterruptTime();
if ((ULONGLONG)InterruptTime.QuadPart >= Timer->DueTime.QuadPart)
{
/* It did, so we don't need to wait */
goto NoWait;
}
/* It didn't, so activate it */
Timer->Header.Inserted = TRUE;
/* Handle Kernel Queues */
if (Thread->Queue) KiActivateWaiterQueue(Thread->Queue);
/* Setup the wait information */
Thread->State = Waiting;
/* Add the thread to the wait list */
KiAddThreadToWaitList(Thread, Swappable);
/* Insert the timer and swap the thread */
ASSERT(Thread->WaitIrql <= DISPATCH_LEVEL);
KiSetThreadSwapBusy(Thread);
KxInsertTimer(Timer, Hand);
WaitStatus = (NTSTATUS)KiSwapThread(Thread, KeGetCurrentPrcb());
/* Check if were swapped ok */
if (WaitStatus != STATUS_KERNEL_APC)
{
/* This is a good thing */
if (WaitStatus == STATUS_TIMEOUT) WaitStatus = STATUS_SUCCESS;
/* Return Status */
return WaitStatus;
}
/* Recalculate due times */
Interval = KiRecalculateDueTime(OriginalDueTime,
&DueTime,
&NewDueTime);
}
WaitStart:
/* Setup a new wait */
Thread->WaitIrql = KeRaiseIrqlToSynchLevel();
KxDelayThreadWait();
KiAcquireDispatcherLockAtDpcLevel();
}
/* We're done! */
KiReleaseDispatcherLock(Thread->WaitIrql);
return WaitStatus;
NoWait:
/* There was nothing to wait for. Did we have a wait interval? */
if (!Interval->QuadPart)
{
/* Unlock the dispatcher and do a yield */
KiReleaseDispatcherLock(Thread->WaitIrql);
return NtYieldExecution();
}
/* Unlock the dispatcher and adjust the quantum for a no-wait */
KiReleaseDispatcherLockFromDpcLevel();
KiAdjustQuantumThread(Thread);
return STATUS_SUCCESS;
}
// Note that the Windows API Sleep(0) will also call NtYieldExecution(), refer to
// the function Ntoskrnl.KeDelayExecutionThread above
The timeouts of the .NET Sleep(1), Sleep(0), Yield() and empty statement:
for (; ; )
{
Stopwatch sw = Stopwatch.StartNew();
// Thread.Sleep(1); // between 36000 and 39000
// Thread.Sleep(0); // 2 or 3
Thread.Yield(); // 1 or 2
// empty statement // always 0
Console.WriteLine(sw.ElapsedTicks);
sw.Restart();
}
The Stopwatch depends on the WinAPI functions QueryPerformanceCounter and QueryPerformanceFrequency:
static Stopwatch() {
bool succeeded = SafeNativeMethods.QueryPerformanceFrequency(out Frequency);
if(!succeeded) {
IsHighResolution = false;
Frequency = TicksPerSecond;
tickFrequency = 1;
}
else {
IsHighResolution = true;
tickFrequency = TicksPerSecond;
tickFrequency /= Frequency;
}
}
public static long GetTimestamp() {
if(IsHighResolution) {
long timestamp = 0;
SafeNativeMethods.QueryPerformanceCounter(out timestamp);
return timestamp;
}
else {
return DateTime.UtcNow.Ticks;
}
}
The Stopwatch is exact, but neither DateTime.UtcNow.Ticks nor Environment.TickCount is exact:
// Stopwatch is extremely exact without Thread.Sleep, always 1000.00 ms
// But the combination of Stopwatch + Thread.Sleep(1000) is inexact
// Stopwatch is very exact with Thread.Sleep + a spin check, always 1000 ms
thread = new Thread(() =>
{
var setText = new Action<long>(t => textBox1.Text
= Math.Round(t * 1000.0 / Stopwatch.Frequency, 2).ToString());
var sw = Stopwatch.StartNew();
for (; ; )
{
// In most cases 986 is exact enough, but very rarely it might produce
// a "1001", so use 985 here
Thread.Sleep(985);
while (sw.ElapsedTicks < Stopwatch.Frequency)
// Use Sleep(0) instead of Yield() or empty statement
Thread.Sleep(0);
// The actual interval is always 1000 ms instead of 1014.01 ms
// The Invoke method must be used since InvokeRequired is true
Invoke(setText, sw.ElapsedTicks);
sw.Restart();
}
});
thread.Start();
// DateTime.UtcNow.Ticks and DateTime.Now.Ticks are both inexact with
// Thread.Sleep + a spin check, still 1014.01 ms
thread = new Thread(() =>
{
var setText = new Action<long>(t => textBox1.Text
= Math.Round((t - ticks) / 10000.0, 2).ToString());
for (; ; )
{
Thread.Sleep(985);
while (DateTime.UtcNow.Ticks < ticks + 10000000)
Thread.Sleep(0);
var t = DateTime.UtcNow.Ticks;
Invoke(setText, t);
ticks = t;
}
});
thread.Start();
// Environment.TickCount is inexact with Thread.Sleep + a spin check,
// still 1014 ms (int value)
thread = new Thread(() =>
{
var setText = new Action<int>(t => textBox1.Text
= (t - msecs).ToString());
for (; ; )
{
Thread.Sleep(985);
while (Environment.TickCount < msecs + 1000)
Thread.Sleep(0);
var t = Environment.TickCount;
Invoke(setText, t);
msecs = t;
}
});
thread.Start();
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
thread.Abort();
}
References:
Source code of the ReactOS
Official Reference Source of the .NET 4.5 Update 1
The Shared Source CLI 2.0 (for native functions)
SwitchToThread/Thread.Yield vs. Thread.Sleep(0) vs. Thead.Sleep(1)
Thanks to everyone for help!
Sleep causes the OS to not schedule the thread until the time is up. Note that schedule != run.
Scheduling only adds the thread to a queue so it'll get run eventually, but not always immediately. For instance, if there's already a thread running, you still need to wait for its time slice to finish. If there are higher-priority threads in the queue, those could also run before it.
You should never count on Sleep() lasting exactly the amount of time you give it -- only at least that amount of time.
Timers basically operate the same way, but don't block a thread while they're waiting to be scheduled.
Also, you should be using Environment.TickCount or Stopwatch to measure elapsed time, not DateTime, which is affected by changes to the system time.
You can call timeBeginPeriod to tighten up the timer resolution. This also affects GetTickCount.
See Why does increasing timer resolution via timeBeginPeriod impact power consumption? for a discussion of why you might not want to do this (no idea whether this would be a concern in your situation of course).
why not use Stopwatch?
it's very precise
MSDN Stopwatch
If you need a Real-time Operating System, you need to look someplace else other than a Windows desktop OS.
For example: List of real-time operating systems
Your keyphrase is "multimedia timers".
You should not rely on Timer/Sleep interval for time sensitive calculations - it will never be exact. You can use Ticks instead or other high precision techniques. Resolution of Ticks is 1ms on Windows 7, according to this answer.
Also see here for more information: How to make an accurate decimal Timer?
The Windows OS is simply not designed for such things. This is a slight drawback to any OS that supports context switching. If you need very precise timings you'll need to use an embedded system or an OS that is designed to behave this way.
There are methods that will certainly improve the timing accuracy of whatever behavior you're trying to produce but it will be unreliable at best. At the end of the day the operating system is free to force a context switch which could delay your timer at any time.
Wikipedia has some more info on the subject: http://en.wikipedia.org/wiki/Real-time_operating_system

How make time elapsed method?

I need a method that give me the time elapsed awhile my process. I call it at start the process and call it again at finish the process, and the method print the total time elapsed.
This is my method, but always print the time in 00:00. Why is happening this??
public void GetTimeElapsed(string filePath, int logSelected, bool time, IUserOptions userOptions)
{
var stopwatch = new System.Diagnostics.Stopwatch();
LogBinaryWriter BinaryWriter = new LogBinaryWriter();
string timeElapsed = "";
if(time == true)
{
stopwatch.Start();
}
if (time == false)
{
stopwatch.Stop();
TimeSpan timeSpan = stopwatch.Elapsed;
timeElapsed = (string.Format("\nFile Generated: {0}\nTime Elapsed: {1} minute(s) {2} second(s)",
BinaryWriter.CreateLogFileName(filePath, Convert.ToInt32(logSelected)),
timeSpan.Minutes, timeSpan.Seconds, timeSpan.Milliseconds / 10 + "\n"));
userOptions.DisplayUserMessage(timeElapsed);
}
}
Look where you're declaring stopwatch; it's a local variable. That means you're creating and using two different stopwatches; the first one is started when you call the method with a "true" parameter, then disposed of when the method ends and the variable goes out of scope. The second is declared, never started, then its time examined and logged.
To solve the problem, declare an instance variable ("field") for the Stopwatch. That will keep it in scope as long as the object is around, meaning it will keep running after the method ends, and will still be the same instance when you come back to it to stop and examine it.
Your stopwatch variable is local. When you call the function a second time, it's initialized again.
You need to move the declaration up to class level.
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
public void GetTimeElapsed(string filePath, int logSelected, bool time, IUserOptions userOptions)
{
... etc
You're creating a new stopwatch each time this method is called, but it looks like that should be persistent between method calls.
Take the stopwatch variable declaration outside of the method.
What about using:
var startTime = DateTime.Now;
... your code
var elapsed = DateTime.Now - startTime;
if(time == true)
{
stopwatch.Start();
}
if (time == false)
{
stopwatch.Stop();
...
}
If time is true, you only ever start the stopwatch.
If it is false, you never start it.
A better structure would be:
if(time)
{
stopwatch.Start();
}
... //code to measure here
if (time)
{
stopwatch.Stop();
// log elapsed time
}
Note:
If you have a boolean type, you don't compare it to true or false. Just use it directly and if you want to invert it just use !.
You need to use timeSpan.TotalMinutes instead timestamp.Minutes. Refer timespan documentation

Any class in C# that can tell me clock tick, seconds consumed by a function

Is there a class in C# that can give me clock ticks, seconds consumed by a method? I guess I have two wrap that functionality around function to time the ticks and seconds taken up.
You could use the System.Diagnostics.Stopwatch class.
Stopwatch sw = new Stopwatch();
sw.Start();
// Your method call here...
sw.Stop();
// Get the elapsed time
TimeSpan elapsed = sw.Elapsed;
From here, you can use the TimeSpan.Ticks or the TimeSpan.TotalSeconds properties to determine the elapsed ticks or elapsed seconds, respectively.
If you wanted to, you could use a method along the following lines to "wrap" that functionality around a function, as you mentioned (just an idea, you'd probably want to tweak this code to suit your specific purposes -- passing in arguments, etc.):
public static T ExecuteWithElapsedTime<T>(Func<T> function, out TimeSpan elapsedTime)
{
T rval;
Stopwatch sw = new Stopwatch();
sw.Start();
rval = function();
sw.Stop();
elapsedTime = sw.Elapsed;
return rval;
}
And you could call it like this (where myFunc is a function that returns an int):
TimeSpan elapsed;
int result = ExecuteWithElapsedTime(myFunc, out elapsed);
Might be simpler though to not even bother with a method like this, and just put the Stopwatch code inline with your method call.
Use:
using System.Diagnostics;
...
var sw = Stopwatch.StartNew();
DoYaThing();
Console.WriteLine("{0} Elapsed", sw.Elapsed);
There's the high resolution timer ...
Also, iirc a TimeSpan can give you a measurement in ticks back.
You can check out the [System.TimeSpan] class and wrap that around your method.

Categories

Resources