Useful for doing operation performance timing in C#.
using System;
using System.Diagnostics;
public class OperationTimer : IDisposable
{
private Stopwatch _stopwatch;
private String _text;
private Int32 _collectionCount;
public OperationTimer(String text)
{
PrepareForOperation();
_text = text;
_collectionCount = GC.CollectionCount(0);
// This should be the last statement in this
// method to keep timing as accurate as possible
_stopwatch = Stopwatch.StartNew();
}
public void Dispose()
{
Console.WriteLine("{0} (GCs={1,3}) {2}", (_stopwatch.Elapsed),
GC.CollectionCount(0) - _collectionCount, _text);
}
private static void PrepareForOperation()
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
//
// Usage
public static void ValueTypePerfTest()
{
const Int32 count = 100000000;
using(new OperationTimer("List<Int32>"))
{
List<Int32> l = new List<Int32>();
for (Int32 n = 0; n < count; n++)
{
l.Add(n); // No boxing
Int32 x = l[n]; // No unboxing
}
l = null; // Make sure this gets GC'd
}
using(new OperationTimer("ArrayList of Int32"))
{
ArrayList a = new ArrayList();
for (Int32 n = 0; n < count; n++)
{
a.Add(n); // Boxing
Int32 x = (Int32)a[n]; // Unboxing
}
a = null; // Make sure this gets GC'd
}
}
public static void ReferenceTypePerfTest()
{
const Int32 count = 100000000;
using(new OperationTimer("List<String>"))
{
List<String> l = new List<String>();
for (Int32 n = 0; n < count; n++)
{
l.Add("X"); // Reference copy
String x = l[n]; // Reference copy
}
l = null; // Make sure this gets GC'd
}
using(new OperationTimer("ArrayList of String"))
{
ArrayList a = new ArrayList();
for (Int32 n = 0; n < count; n++)
{
a.Add("X"); // Reference copy
String x = (String)a[n]; // Cast check & reference copy
}
a = null; // Make sure this gets GC'd
}
}