Skip to content

Instantly share code, notes, and snippets.

@kenegozi
Created January 1, 2010 21:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kenegozi/24b9012a49392c4e458b to your computer and use it in GitHub Desktop.
Save kenegozi/24b9012a49392c4e458b to your computer and use it in GitHub Desktop.
class Generator
{
int val;
object locker = new object();
public int GetNonLocked()
{
return val++;
}
public int GetLocked()
{
lock (locker)
return val++;
}
public int GetInterlocked()
{
// Interlocked.Increment is doing ++value and not value++, so we decrement 1
// of the resulted operation
return Interlocked.Increment(ref val) - 1;
}
}
internal class Program
{
public static void Main()
{
var gen = new Generator();
var many = 100000;
var repeats = 10;
double nonLocked = 0, locked = 0, interlocked = 0;
gen = new Generator();
repeats.TimesDo(() => nonLocked += MeasureTime(() => many.TimesDo(() => gen.GetNonLocked())));
gen = new Generator();
repeats.TimesDo(() => locked += MeasureTime(() => many.TimesDo(() => gen.GetLocked())));
gen = new Generator();
repeats.TimesDo(() => interlocked += MeasureTime(() => many.TimesDo(() => gen.GetInterlocked())));
Console.WriteLine("avg time for no-lock is {0} milliseconds", nonLocked / repeats);
Console.WriteLine("avg time for lock is {0} milliseconds", locked / repeats);
Console.WriteLine("avg time for interlock is {0} milliseconds", interlocked / repeats);
nonLocked = 0; locked = 0; interlocked = 0;
gen = new Generator();
repeats.TimesDo(() => nonLocked += MeasureTime(() => many.TimesDoAsync(() => gen.GetNonLocked())));
gen = new Generator();
repeats.TimesDo(() => locked += MeasureTime(() => many.TimesDoAsync(() => gen.GetLocked())));
gen = new Generator();
repeats.TimesDo(() => interlocked += MeasureTime(() => many.TimesDoAsync(() => gen.GetInterlocked())));
Console.WriteLine("avg time for async no-lock is {0} milliseconds", nonLocked / repeats);
Console.WriteLine("avg time for async lock is {0} milliseconds", locked / repeats);
Console.WriteLine("avg time for async interlock is {0} milliseconds", interlocked / repeats);
}
static void MeasureTime(Action action)
{
var watch = Stopwatch.StartNew();
action();
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds + "milliseconds");
}
}
static class IntTimesDoExtension
{
public static void TimesDo(this int times, Action action)
{
for (var i = 0; i < times; ++i)
action();
}
public static void TimesDoAsync(this int times, Action action)
{
SpawnAndWait(times, action);
}
static void SpawnAndWait(int count, Action action)
{
var reset = new ManualResetEvent(false);
var completed = count;
for (var i = 0; i < count; ++i)
{
ThreadPool.QueueUserWorkItem(d =>
{
action();
if (Interlocked.Decrement(ref completed) == 0)
reset.Set();
});
}
WaitHandle.WaitAll(new[] { reset });
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment