There are data, there is truth, I believe that everyone in peacetime work or learning process, you need to compare several different methods or the performance gap between the implementation. At these times, it is often necessary for us to constantly create stopwatch, open, close, and then print time. This repetition will one day be unbearable, so if you can have a "standard" performance counter, it should make life much easier. This performance counter is not complex, it is good enough, and do not need to consider extensibility, to expand the direct modification of the code is enough, but also do not need to consider the output format, directly printed in the console on the line.
In the last. NET technology conference, Jeffrey Richter in keynote session in a "the performance of Everyday things" keynote speech, showing the various common programming elements of performance comparisons. In the demo he used a simple counter called Codetimer to count the performance of each practice. It was a shame that we didn't find out where Uncle Jr was going to expose the implementation of this counter. Forget it, then write one out by impression, it's not complicated anyway.
In general, Codetimer has two public methods, one is initialize, the other is time:
public static class CodeTimer
{
public static void Initialize()
{
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
Thread.CurrentThread.Priority = ThreadPriority.Highest;
Time("", 1, () => { });
}
public static void Time(string name, int iteration, Action action)
{
...
}
}
The
Codetimer.initialize method should be called before the test starts. First, it sets the current process and the current thread's priority to the highest, which in turn can reduce the disruption caused by operating system scheduling. Then call the time method to "Preheat", let the JIT compile the cost of the IL code, let the method "enter State" as soon as possible. The time method is really a method for performance counting, implemented as follows:
public static void time (string name, int iteration, action action)
{
if (string.isnullorempty (name)) Retu Rn
//1.
Consolecolor currentforecolor = Console.foregroundcolor;
Console.foregroundcolor = Consolecolor.yellow;
Console.WriteLine (name);
//2.
GC. Collect (GC. Maxgeneration, gccollectionmode.forced);
int[] gccounts = new INT[GC. Maxgeneration + 1];
for (int i = 0; I <= GC. Maxgeneration; i++)
{
Gccounts[i] = GC. Collectioncount (i);
}
//3.
Stopwatch watch = new stopwatch ();
Watch. Start ();
ULong Cyclecount = Getcyclecount ();
for (int i = 0; i < iteration i++) action ();
ULong cpucycles = Getcyclecount ()-cyclecount;
Watch. Stop ();
//4.
Console.foregroundcolor = Currentforecolor;
Console.WriteLine ("\ttime elapsed:\t" + watch.) Elapsedmilliseconds.tostring ("N0") + "MS");
Console.WriteLine ("\tcpu cycles:\t" + cpucycles.tostring ("N0"));
//5.
for (int i = 0; I <= GC. MaxgEneration; i++)
{
int count = GC. Collectioncount (i)-gccounts[i];
Console.WriteLine ("\tgen" + i + ": \t\t" + count);
}
Console.WriteLine ();
}
private static ULONG Getcyclecount ()
{
ULong cyclecount = 0;
Querythreadcycletime (GetCurrentThread (), ref cyclecount);
return cyclecount;
}
[DllImport ("kernel32.dll")]
[Return:marshalas (Unmanagedtype.bool)]
static extern Bool Querythreadcycletime (IntPtr threadhandle, ref ulong cycletime);
[DllImport ("kernel32.dll")]
static extern IntPtr getcurrentthread ();