Public static classCodetimer
{
Public static voidInitialize ()
{
Process. Getcurrentprocess (). priorityclass =Processpriorityclass. High;
Thread. Currentthread. Priority =Threadpriority. Highest;
Time ("", 1, () => {});
}
Public static void Time ( String Name, Int Iteration,Action Action ){ If ( String . Isnullorempty (name )) Return ; // 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" + Count );} Console . Writeline ();} Private Static ulong Getcyclecount (){ Ulong Cyclecount = 0; querythreadcycletime (getcurrentthread (), Ref Cyclecount ); Return Cyclecount ;}[ Dllimport ( "Kernel32.dll" )] [ Return : Financialas ( Unmanagedtype . Bool)]Static extern bool Querythreadcycletime ( Intptr Threadhandle, Ref ulong Cycletime );[ Dllimport ( "Kernel32.dll" )] Static extern Intptr Getcurrentthread ();
}
The time method accepts three parameters: Name, number of cycles, and method body to be executed. Print the time spent, the CPU clock cycle consumed, and the number of garbage collection times. The specific implementation steps are as follows:
- Retain the foreground color of the current console and use the yellow output name parameter.
- Force GC to collect and record the number of times collected by generation.
- RunCodeThe time consumed and the CPU clock cycle 1 are recorded.
- Restore the default foreground color of the console and print the consumed time and CPU clock cycle.
- Print the number of garbage collection times during execution.
Compared with the traditional counting method, this code also outputs more information: the CPU clock cycle and the number of garbage collection times of each generation. The CPU clock cycle is an auxiliary reference in the performance count. It shows the number of time slice allocated by the CPU to this method. It is not necessarily related to the consumed time. For example, the thread. Sleep method will temporarily stop the CPU from "Supplying" to the current thread, which consumes time but saves the CPU clock cycle:
Codetimer. Time ("Thread sleep", 1, () => {Thread. Sleep (3000 );});Codetimer. Time ("Empty method", 10000000, () => {});
The result is as follows: