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
Related
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
Right now, I have the following code that times the completion time of a method and prints it out:
static void Run()
{
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
GetTableNames().Wait();
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedTicks);
}
static async Task GetTableNames() { doesStuff(); }
However, I'll be reusing that timing code a bunch, so I'd like to wrap it inside a method so that I can do something like this:
static void Run()
{
TimeMethod(GetTableNames);
TimeMethod(GetChairNames);
TimeMethod(GetStoolNames);
// etc...
}
I've been trying a few different things (Action, Delegate, Func), but haven't succeeded in finding one that allows me to call .Wait() on the passed function before stopping the timer. Any recommendations?
Declare TimeMethod to take Func<Task>:
TimeMethod(Func<Task> method)
{
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
method().Wait();
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedTicks);
}
I'm looking for some advice on writing unit tests for multi-threading in C#. Specifically, I want to check that an object is being locked correctly. However, in order to test this I need to assert against that object, which may have changed before the assert(s) are implemented (with the lock being released, another thread may change the object).
Using AutoResetEvent I have been able to control the flow in the unit test side, allowing me to effectively emulate the lock in the tested object. The issue with this is that I no longer need the lock for the test to pass.
What I'd like is to have a test that passes with the lock in and fails with it out.
Obviously, this is a simplified example. It's also .Net 4, so there is no async and await option (although if that would help, changing could be an option).
Suggestions welcome. Thanks.
Below is example code:
public class BasicClass
{
public int Val
{
get { lock (lockingObject) { return val; } }
private set { lock (lockingObject) { val = value; } }
}
private int val;
public BasicClass(int val = -1)
{
Val = val;
}
public void SetValue(int val)
{
Val = val;
}
private object lockingObject = new object();
}
This is the (NUnit) unit test:
[Test]
public void BasicClassTest()
{
for (int repeat = 0; repeat < 1000; repeat++) // Purely for dev testing and can get away with as no SetUp/TearDown
{
BasicClass b = new BasicClass();
int taskCount = 10;
Task[] tasks = new Task[taskCount];
var taskControl = new AutoResetEvent(false);
var resultControl = new AutoResetEvent(false);
int expected = -1;
for (int i = 0; i < taskCount; i++)
{
int temp = i;
tasks[temp] = new Task(() =>
{
taskControl.WaitOne(); // Hold there here until set
b.SetValue(temp);
expected = temp;
resultControl.Set(); // Allows asserts to be processed.
});
}
// Start each task
foreach (var t in tasks)
t.Start();
// Assert results as tasks finish.
for (int i = 0; i < taskCount; i++)
{
taskControl.Set(); // Unblock, allow one thread to proceed.
resultControl.WaitOne(); // Wait for a task to set a expected value
Assert.That(b.Val, Is.EqualTo(expected));
Console.WriteLine("b.Val = {0}, expected = {1}", b.Val, expected); // Output values to ensure they are changing
}
// Wait for all tasks to finish, but not forever.
Task.WaitAll(tasks, 1000);
}
}
As for other system functions like DateTime.Now, I prefer to abstract threading functions like sleep, mutex, signals and so on (yes, I know there are libraries for DateTime.Now and other system functions, but I think to abstract it is a better way).
So you end up with a kind of IThreadind interface with methods to Sleep and so on. The disadvantage is, that you can't use the handy lock statement in this case. You could have a method Lock(object) that returns you an IDisposable that you can use with the "using" statement, to get nearly the same comfort.
using(threading.Lock(lockObject))
{
...
}
Now you can Create a real implementation with the real functions and a Mock for your unit tests which is injected. So you could for example for your tests shortcut any sleep call to e few ms in order to speed up your tests. And you can verify that all functions where called that you expected.
Sounds like a lot of work? Think over, how many time you will spend to debug some nasty threading issue which from time to time crashes your production system with your customer running amok.
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().
My scenario:
I have a computation that should be run about once a second. After it is run there should be a wait of about 200ms for other stuff to catch up. If the compuation is still running after a second it should be started a second time, but should the program should wait until it is finished and start the next computation 200ms after finishing.
The way I am doing it now:
_refreshFinished = new Subject<bool>();
_autoRefresher = Observable.Interval(TimeSpan.FromMilliseconds(1000))
.Zip(_refreshFinished, (x,y) => x)
.Subscribe(x => AutoRefresh(stuff));
The problem with this code is, that i see no way to put in a delay after a computation finished.
The Delay method only delays the first element of the observable collection. Usually this behaviour is the right once, since you would have to buffer an endless amount of elements if you wanted to buffer everyone, but since delaying the call to Autorefesh by 200ms delays the output of _refreshFinished by 200ms as well there would be no buffer overhead.
Basicly I want an Observable that fires every every MaxTime(some_call,1000ms) then gets delayed by 200ms or even better, some dynamic value. At this point i dont even really care about the values that are running through this, although that might change in the future.
I´m open to any suggestions
Observable.Generate() has a number of overloads which will let you dynamically adjust the time in which the next item is created.
For instance
IScheduler schd = Scheduler.TaskPool;
var timeout = TimeSpan.FromSeconds(1);
var shortDelay = TimeSpan.FromMilliseconds(200);
var longerDelay = TimeSpan.FromMilliseconds(500);
Observable.Generate(schd.Now,
time => true,
time => schd.Now,
time => new object(), // your code here
time => schd.Now.Subtract(time) > timeout ? shortDelay : longerDelay ,
schd);
This sounds more like a job for the new async framework http://msdn.microsoft.com/en-us/vstudio/gg316360
There is a way to do it. Its not the easiest thing ever, since the wait time has to be dynamicly calculated on each value but it works and is pretty generic.
When you use thise code you can just insert the code that should be called in YOURCODE and everything else works automaticly. You code will be basicly be called every Max(yourCodeTime+extraDelay,usualCallTime+extraDelay). This means yourCode wont be called twice at the same time and the app will always have extraDelay of time to do other stuff.
If there is some easier/other way to do this i would ove to hear it.
double usualCallTime = 1000;
double extraDealy = 100;
var subject = new Subject<double>();
var subscription =
sub.TimeInterval()
.Select(x =>
{
var processingTime = x.Interval.TotalMilliseconds - x.Value;
double timeToWait =
Math.Max(0, usualCallTime - processingTime) + extraDelay;
return Observable.Timer(TimeSpan.FromMilliseconds(timeToWait))
.Select(ignore => timeToWait);
})
.Switch()
.Subscribe(x => {YOURCODE();sub.OnNext(x)});
sub.OnNext(0);
private static void YOURCODE()
{
// do stuff here
action.Invoke();
}
If I understand your problem correctly, you have a long-running compute function such as this:
static String compute()
{
int t = 300 + new Random().Next(1000);
Console.Write("[{0}...", t);
Thread.Sleep(t);
Console.Write("]");
return Guid.NewGuid().ToString();
}
And you want to call this function at least once per second but without overlapping calls, and with a minimum 200ms recovery time between calls. The code below works for this situation.
I started with a more functional approach (using Scan() and Timestamp()), more in the style of Rx--because I was looking for a good Rx exercise--but in the end, this non-aggregating approach was just simpler.
static void Main()
{
TimeSpan period = TimeSpan.FromMilliseconds(1000);
TimeSpan recovery = TimeSpan.FromMilliseconds(200);
Observable
.Repeat(Unit.Default)
.Select(_ =>
{
var s = DateTimeOffset.Now;
var x = compute();
var delay = period - (DateTimeOffset.Now - s);
if (delay < recovery)
delay = recovery;
Console.Write("+{0} ", (int)delay.TotalMilliseconds);
return Observable.Return(x).Delay(delay).First();
})
.Subscribe(Console.WriteLine);
}
Here's the output:
[1144...]+200 a7cb5d3d-34b9-4d44-95c9-3e363f518e52
[1183...]+200 359ad966-3be7-4027-8b95-1051e3fb20c2
[831...]+200 f433b4dc-d075-49fe-9c84-b790274982d9
[766...]+219 310c9521-7bee-4acc-bbca-81c706a4632a
[505...]+485 0715abfc-db9b-42e2-9ec7-880d7ff58126
[1244...]+200 30a3002a-924a-4a64-9669-095152906d85
[1284...]+200 e5b1cd79-da73-477c-bca0-0870f4b5c640
[354...]+641 a43c9df5-53e8-4b58-a0df-7561cf4b0483
[1094...]+200 8f25019c-77a0-4507-b05e-c9ab8b34bcc3
[993...]+200 840281bd-c8fd-4627-9324-372636f8dea3
[edit: this sample uses Rx 2.0(RC) 2.0.20612.0]
Suppose you have an existing 'IObservable' , then the following will work
var delay = TimeSpan.FromSeconds(1.0);
var actual = source.Scan(
new ConcurrentQueue<object>(),
(q, i) =>
{
q.Enqueue(i);
return q;
}).CombineLatest(
Observable.Interval(delay),
(q, t) =>
{
object item;
if (q.TryDequeue(out item))
{
return item;
}
return null;
}).Where(v => v != null);
'actual' is your resultant observable. But keep in mind that the above code has turned that into a Hot observable if it wasn't hot already. So you won't get 'OnCompleted' called.