namespace TestConsoleApplication { using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Diagnostics; using Microshaoft; class Program { static void Main(string[] args) { Console.WriteLine("Begin ..."); int sleep = 10; int iterations = 1000; int maxDegreeOfParallelism = Environment.ProcessorCount; EasyCodeTimerPlus.ParallelTime ( "未加载性能计数器 ParallelTime" , iterations , () => { Thread.Sleep(sleep); } , maxDegreeOfParallelism , false ); EasyCodeTimerPlus.ParallelTime ( "已加载性能计数器 ParallelTime" , iterations , () => { Thread.Sleep(sleep); } , maxDegreeOfParallelism , true ); Console.WriteLine("End ..."); Console.ReadLine(); } } } namespace Microshaoft { using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; public static class EasyCodeTimerPlus { private const string _performanceCountersCategory = "Microshaoft EasyCodeTimerPlus Performance Test Counters Category"; private static readonly string _processName = Process.GetCurrentProcess().ProcessName; public static void Initialize() { Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High; Thread.CurrentThread.Priority = ThreadPriority.Highest; Time("", 1, () => { }, false); } public static void ParallelTime ( string name , int iterations , Action actionOnce , int maxDegreeOfParallelism //= 1 , bool enablePerformanceCounters //= false ) { PerformanceCountersContainer pcc = null; if (enablePerformanceCounters) { pcc = new PerformanceCountersContainer(); pcc.AttachPerformanceCountersToProperties ( string.Format ( "{2}{0}{3}{1}{4}" , ": " , " @ " , "ParallelTime" , name , _processName ) , _performanceCountersCategory ); } // 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 = Stopwatch.StartNew(); ulong cycleCount = GetCycleCount(); Parallel.For ( 0 , iterations , new ParallelOptions() { MaxDegreeOfParallelism = maxDegreeOfParallelism //, TaskScheduler = null } , (x) => { ProcessOnce(actionOnce, pcc); } ); ulong cpuCycles = GetCycleCount() - cycleCount; watch.Stop(); //watch = null; // 4. Console.ForegroundColor = currentForeColor; Console.WriteLine ( "{0}Time Elapsed:{0}{1}ms" , "\t" , watch.ElapsedMilliseconds.ToString("N0") ); Console.WriteLine ( "{0}CPU Cycles:{0}{1}" , "\t" , cpuCycles.ToString("N0") ); // 5. for (int i = 0; i <= GC.MaxGeneration; i++) { int count = GC.CollectionCount(i) - gcCounts[i]; Console.WriteLine ( "{0}Gen{1}:{0}{0}{2}" , "\t" , i , count ); } Console.WriteLine(); } public static void Time ( string name , int iterations , Action actionOnce , bool enablePerformanceCounters //= false ) { ParallelTime ( name , iterations , actionOnce , 1 , enablePerformanceCounters ); } private static void ProcessOnce ( Action actionOnce , PerformanceCountersContainer container //= null ) { if (container != null) { container.PrcocessPerformanceCounter.Increment(); container.ProcessingPerformanceCounter.Increment(); container.ProcessedAverageTimerPerformanceCounter.ChangeAverageTimerCounterValueWithTryCatchExceptionFinally ( true , container.ProcessedAverageBasePerformanceCounter , () => { actionOnce(); } , null , null ); container.ProcessingPerformanceCounter.Decrement(); container.ProcessedPerformanceCounter.Increment(); container.ProcessedRateOfCountsPerSecondPerformanceCounter.Increment(); } else { actionOnce(); } } 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(); } } namespace Microshaoft { using System.Diagnostics; public static class PerformanceCounterHelper { public static CounterCreationData GetCounterCreationData(string counterName, PerformanceCounterType performanceCounterType) { return new CounterCreationData() { CounterName = counterName , CounterHelp = string.Format("{0} Help", counterName) , CounterType = performanceCounterType }; } } } namespace Microshaoft { using System; using System.Diagnostics; //using System.Collections.Concurrent; public class PerformanceCountersContainer { #region PerformanceCounters private PerformanceCounter _processPerformanceCounter; [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.NumberOfItems64)] public PerformanceCounter PrcocessPerformanceCounter { private set { ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _processPerformanceCounter, value, 2); } get { return _processPerformanceCounter; } } private PerformanceCounter _processedPerformanceCounter; [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.NumberOfItems64)] public PerformanceCounter ProcessedPerformanceCounter { private set { ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _processedPerformanceCounter, value, 2); } get { return _processedPerformanceCounter; } } private PerformanceCounter _processingPerformanceCounter; [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.NumberOfItems64)] public PerformanceCounter ProcessingPerformanceCounter { private set { ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _processingPerformanceCounter, value, 2); } get { return _processingPerformanceCounter; } } private PerformanceCounter _processedRateOfCountsPerSecondPerformanceCounter; [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.RateOfCountsPerSecond64)] public PerformanceCounter ProcessedRateOfCountsPerSecondPerformanceCounter { private set { ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _processedRateOfCountsPerSecondPerformanceCounter, value, 2); } get { return _processedRateOfCountsPerSecondPerformanceCounter; } } private PerformanceCounter _ProcessedAverageTimerPerformanceCounter; [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.AverageTimer32)] public PerformanceCounter ProcessedAverageTimerPerformanceCounter { private set { ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _ProcessedAverageTimerPerformanceCounter, value, 2); } get { return _ProcessedAverageTimerPerformanceCounter; } } private PerformanceCounter _processedAverageBasePerformanceCounter; [PerformanceCounterTypeAttribute(CounterType = PerformanceCounterType.AverageBase)] public PerformanceCounter ProcessedAverageBasePerformanceCounter { private set { ReaderWriterLockSlimHelper.TryEnterWriterLockSlimWrite<PerformanceCounter>(ref _processedAverageBasePerformanceCounter, value, 2); } get { return _processedAverageBasePerformanceCounter; } } #endregion // indexer declaration public PerformanceCounter this[string name] { get { throw new NotImplementedException(); //return null; } } private bool _isAttachedPerformanceCounters = false; public void AttachPerformanceCountersToProperties ( string instanceName , string categoryName ) { if (!_isAttachedPerformanceCounters) { var type = this.GetType(); PerformanceCountersHelper.AttachPerformanceCountersToProperties<PerformanceCountersContainer>(instanceName, categoryName, this); } _isAttachedPerformanceCounters = true; } } } namespace Microshaoft { using System; using System.Diagnostics; [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] public class PerformanceCounterTypeAttribute : Attribute { public PerformanceCounterType CounterType; } } namespace Microshaoft { using System.Diagnostics; using System.Linq; public static class PerformanceCountersHelper { public static void AttachPerformanceCountersToProperties<T> ( string performanceCounterInstanceName , string category , T target //= default(T) ) { var type = typeof(T); var propertiesList = type.GetProperties().ToList(); propertiesList = propertiesList.Where ( (pi) => { var parameters = pi.GetIndexParameters(); return ( pi.PropertyType == typeof(PerformanceCounter) && (parameters == null ? 0 : parameters.Length) <= 0 ); } ).ToList(); if (PerformanceCounterCategory.Exists(category)) { propertiesList.ForEach ( (pi) => { if (PerformanceCounterCategory.CounterExists(pi.Name, category)) { if (PerformanceCounterCategory.InstanceExists(performanceCounterInstanceName, category)) { //var pc = new PerformanceCounter(category, pi.Name, instanceName, false); //pc.InstanceName = instanceName; //pc.RemoveInstance(); } } } ); //PerformanceCounterCategory.Delete(category); } if (!PerformanceCounterCategory.Exists(category)) { var ccdc = new CounterCreationDataCollection(); propertiesList.ForEach ( (pi) => { var propertyName = pi.Name; PerformanceCounterTypeAttribute attribute = pi.GetCustomAttributes(false).FirstOrDefault ( (x) => { return x as PerformanceCounterTypeAttribute != null; } ) as PerformanceCounterTypeAttribute; PerformanceCounterType performanceCounterType = (attribute == null ? PerformanceCounterType.NumberOfItems64 : attribute.CounterType); var ccd = PerformanceCounterHelper.GetCounterCreationData ( propertyName , performanceCounterType ); ccdc.Add(ccd); } ); PerformanceCounterCategory.Create ( category, string.Format("{0} Category Help.", category), PerformanceCounterCategoryType.MultiInstance, ccdc ); } propertiesList.ForEach ( (pi) => { var propertyName = pi.Name; var pc = new PerformanceCounter() { CategoryName = category , CounterName = propertyName , InstanceLifetime = PerformanceCounterInstanceLifetime.Process , InstanceName = performanceCounterInstanceName , ReadOnly = false , RawValue = 0 }; if (pi.GetGetMethod().IsStatic) { var setter = DynamicPropertyAccessor.CreateSetStaticPropertyValueAction<PerformanceCounter>(type, propertyName); setter(pc); } else { if (target != null) { var setter = DynamicPropertyAccessor.CreateSetPropertyValueAction<PerformanceCounter>(type, propertyName); setter(target, pc); } } } ); } } } namespace Microshaoft { using System; using System.Diagnostics; public static class PerformanceCounterExtensionMethodsManager { public static T ChangeCounterValueWithTryCatchExceptionFinally<T> ( this PerformanceCounter performanceCounter , bool enabled , Func<PerformanceCounter, T> OnCounterChangeProcessFunc //= null , Action<PerformanceCounter> OnCounterChangedProcessAction //= null , Func<PerformanceCounter, Exception, bool> OnCaughtExceptionProcessFunc //= null , Action<PerformanceCounter> OnCaughtExceptionFinallyProcessAction //= null ) { T r = default(T); if (enabled) { if (OnCounterChangeProcessFunc != null) { var catchedException = false; try { r = OnCounterChangeProcessFunc(performanceCounter); } catch (Exception e) { catchedException = true; if (OnCaughtExceptionProcessFunc != null) { var b = OnCaughtExceptionProcessFunc(performanceCounter, e); if (b) { throw new Exception("OnCounterChangeProcessFunc InnerExcepion", e); } } } finally { if (catchedException) { if (OnCaughtExceptionFinallyProcessAction != null) { OnCaughtExceptionFinallyProcessAction(performanceCounter); } } } } } if (OnCounterChangedProcessAction != null) { var catchedException = false; try { OnCounterChangedProcessAction(performanceCounter); } catch (Exception e) { catchedException = true; if (OnCaughtExceptionProcessFunc != null) { var b = OnCaughtExceptionProcessFunc(performanceCounter, e); if (b) { throw new Exception("OnCounterChangedProcessAction InnerExcepion", e); } } } finally { if (catchedException) { if (OnCaughtExceptionFinallyProcessAction != null) { OnCaughtExceptionFinallyProcessAction(performanceCounter); } } } } return r; } public static void ChangeAverageTimerCounterValueWithTryCatchExceptionFinally ( this PerformanceCounter performanceCounter , bool enabled , PerformanceCounter basePerformanceCounter , Action OnCounterInnerProcessAction //= null , Func<PerformanceCounter, Exception, bool> OnCaughtExceptionProcessFunc //= null , Action<PerformanceCounter, PerformanceCounter> OnCaughtExceptionFinallyProcessAction //= null ) { if (enabled) { var stopwatch = Stopwatch.StartNew(); if (OnCounterInnerProcessAction != null) { var catchedException = false; try { OnCounterInnerProcessAction(); } catch (Exception e) { catchedException = true; if (OnCaughtExceptionProcessFunc != null) { var b = OnCaughtExceptionProcessFunc(performanceCounter, e); if (b) { throw new Exception("OnCounterInnerProcessAction InnerExcepion", e); } } } finally { stopwatch.Stop(); performanceCounter.IncrementBy(stopwatch.ElapsedTicks); stopwatch = null; basePerformanceCounter.Increment(); if (catchedException) { if (OnCaughtExceptionFinallyProcessAction != null) { OnCaughtExceptionFinallyProcessAction(performanceCounter, basePerformanceCounter); } } } } } } } } namespace Microshaoft { using System; using System.Threading; public static class ReaderWriterLockSlimHelper { public static bool TryEnterWriterLockSlimWrite<T> ( ref T target , T newValue , int enterTimeOutSeconds ) where T : class { bool r = false; var rwls = new ReaderWriterLockSlim(); int timeOut = Timeout.Infinite; if (enterTimeOutSeconds >= 0) { timeOut = enterTimeOutSeconds * 1000; } try { r = (rwls.TryEnterWriteLock(timeOut)); if (r) { Interlocked.Exchange<T>(ref target, newValue); r = true; } } finally { if (r) { rwls.ExitWriteLock(); } } return r; } public static bool TryEnterWriterLockSlim ( Action action , int enterTimeOutSeconds ) { bool r = false; if (action != null) { var rwls = new ReaderWriterLockSlim(); int timeOut = Timeout.Infinite; if (enterTimeOutSeconds >= 0) { timeOut = enterTimeOutSeconds * 1000; } try { r = (rwls.TryEnterWriteLock(timeOut)); if (r) { action(); r = true; } } finally { if (r) { rwls.ExitWriteLock(); } } } return r; } } } namespace Microshaoft { using System; using System.Linq; using System.Linq.Expressions; public class DynamicPropertyAccessor { public static Func<object, object> CreateGetPropertyValueFunc ( string typeName , string propertyName , bool isTypeFromAssembly //= false ) { Type type; if (isTypeFromAssembly) { var assembly = AppDomain.CurrentDomain.GetAssemblies().First ( (a) => { return a.GetTypes().Any ( (t) => { return (t.FullName == typeName); } ); } ); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateGetPropertyValueFunc(type, propertyName); } public static Func<object, object> CreateGetPropertyValueFunc(Type type, string propertyName) { var target = Expression.Parameter(typeof(object), "p"); var castTarget = Expression.Convert(target, type); var getPropertyValue = Expression.Property(castTarget, propertyName); var castPropertyValue = Expression.Convert(getPropertyValue, typeof(object)); var lambda = Expression.Lambda<Func<object, object>>(castPropertyValue, target); return lambda.Compile(); } public static Func<object, TProperty> CreateGetPropertyValueFunc<TProperty> ( string typeName , string propertyName , bool isTypeFromAssembly //= false ) { Type type; if (isTypeFromAssembly) { var assembly = AppDomain.CurrentDomain.GetAssemblies().First ( (a) => { return a.GetTypes().Any ( (t) => { return (t.FullName == typeName); } ); } ); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateGetPropertyValueFunc<TProperty>(type, propertyName); } public static Func<object, TProperty> CreateGetPropertyValueFunc<TProperty>(Type type, string propertyName) { var target = Expression.Parameter(typeof(object), "p"); var castTarget = Expression.Convert(target, type); var getPropertyValue = Expression.Property(castTarget, propertyName); var lambda = Expression.Lambda<Func<object, TProperty>>(getPropertyValue, target); return lambda.Compile(); } public static Func<TProperty> CreateGetStaticPropertyValueFunc<TProperty> ( string typeName , string propertyName , bool isTypeFromAssembly //= false ) { Type type; if (isTypeFromAssembly) { var assembly = AppDomain.CurrentDomain.GetAssemblies().First ( (a) => { return a.GetTypes().Any ( (t) => { return (t.FullName == typeName); } ); } ); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateGetStaticPropertyValueFunc<TProperty>(type, propertyName); } public static Func<TProperty> CreateGetStaticPropertyValueFunc<TProperty>(Type type, string propertyName) { var property = type.GetProperty(propertyName, typeof(TProperty)); var getPropertyValue = Expression.Property(null, property); var lambda = Expression.Lambda<Func<TProperty>>(getPropertyValue, null); return lambda.Compile(); } public static Func<object> CreateGetStaticPropertyValueFunc(Type type, string propertyName) { var property = type.GetProperty(propertyName); var getPropertyValue = Expression.Property(null, property); var castPropertyValue = Expression.Convert(getPropertyValue, typeof(object)); var lambda = Expression.Lambda<Func<object>>(castPropertyValue, null); return lambda.Compile(); } public static Func<object> CreateGetStaticPropertyValueFunc ( string typeName , string propertyName , bool isTypeFromAssembly //= false ) { Type type; if (isTypeFromAssembly) { var assembly = AppDomain.CurrentDomain.GetAssemblies().First ( (a) => { return a.GetTypes().Any ( (t) => { return (t.FullName == typeName); } ); } ); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateGetStaticPropertyValueFunc(type, propertyName); } public static Action<object, object> CreateSetPropertyValueAction(Type type, string propertyName) { var property = type.GetProperty(propertyName); var target = Expression.Parameter(typeof(object), "p"); var propertyValue = Expression.Parameter(typeof(object), "p"); var castTarget = Expression.Convert(target, type); var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType); var getSetMethod = property.GetSetMethod(); if (getSetMethod == null) { getSetMethod = property.GetSetMethod(true); } var call = Expression.Call(castTarget, getSetMethod, castPropertyValue); var lambda = Expression.Lambda<Action<object, object>>(call, target, propertyValue); return lambda.Compile(); } public static Action<object, object> CreateSetPropertyValueAction ( string typeName , string propertyName , bool isTypeFromAssembly //= false ) { Type type; if (isTypeFromAssembly) { var assembly = AppDomain.CurrentDomain.GetAssemblies().First ( (a) => { return a.GetTypes().Any ( (t) => { return (t.FullName == typeName); } ); } ); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateSetPropertyValueAction(type, propertyName); } public static Action<object, TProperty> CreateSetPropertyValueAction<TProperty>(Type type, string propertyName) { var property = type.GetProperty(propertyName); var target = Expression.Parameter(typeof(object), "p"); var propertyValue = Expression.Parameter(typeof(TProperty), "p"); var castTarget = Expression.Convert(target, type); var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType); var getSetMethod = property.GetSetMethod(); if (getSetMethod == null) { getSetMethod = property.GetSetMethod(true); } var call = Expression.Call(castTarget, getSetMethod, castPropertyValue); return Expression.Lambda<Action<object, TProperty>>(call, target, propertyValue).Compile(); } public static Action<object, TProperty> CreateSetPropertyValueAction<TProperty> ( string typeName , string propertyName , bool isTypeFromAssembly //= false ) { Type type; if (isTypeFromAssembly) { var assembly = AppDomain.CurrentDomain.GetAssemblies().First ( (a) => { return a.GetTypes().Any ( (t) => { return (t.FullName == typeName); } ); } ); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateSetPropertyValueAction<TProperty>(type, propertyName); } public static Action<object> CreateSetStaticPropertyValueAction(Type type, string propertyName) { var property = type.GetProperty(propertyName); var propertyValue = Expression.Parameter(typeof(object), "p"); var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType); var getSetMethod = property.GetSetMethod(); if (getSetMethod == null) { getSetMethod = property.GetSetMethod(true); } var call = Expression.Call(null, getSetMethod, castPropertyValue); var lambda = Expression.Lambda<Action<object>>(call, propertyValue); return lambda.Compile(); } public static Action<object> CreateSetStaticPropertyValueAction ( string typeName , string propertyName , bool isTypeFromAssembly //= false ) { Type type; if (isTypeFromAssembly) { var assembly = AppDomain.CurrentDomain.GetAssemblies().First ( (a) => { return a.GetTypes().Any ( (t) => { return (t.FullName == typeName); } ); } ); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateSetStaticPropertyValueAction(type, propertyName); } public static Action<TProperty> CreateSetStaticPropertyValueAction<TProperty>(Type type, string propertyName) { var property = type.GetProperty(propertyName); var propertyValue = Expression.Parameter(typeof(TProperty), "p"); //var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType); var getSetMethod = property.GetSetMethod(); if (getSetMethod == null) { getSetMethod = property.GetSetMethod(true); } var call = Expression.Call(null, getSetMethod, propertyValue); var lambda = Expression.Lambda<Action<TProperty>>(call, propertyValue); return lambda.Compile(); } public static Action<TProperty> CreateSetStaticPropertyValueAction<TProperty> ( string typeName , string propertyName , bool isTypeFromAssembly //= false ) { Type type; if (isTypeFromAssembly) { var assembly = AppDomain.CurrentDomain.GetAssemblies().First ( (a) => { return a.GetTypes().Any ( (t) => { return (t.FullName == typeName); } ); } ); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateSetStaticPropertyValueAction<TProperty>(type, propertyName); } } } namespace System.Threading.Tasks { using System; using System.Linq; using System.Threading; public class ParallelOptions { public int MaxDegreeOfParallelism { set; get; } } public static class Parallel { public static void For ( int from , int to , ParallelOptions options , Action<int> action ) { var iterations = to - from; var threads = options.MaxDegreeOfParallelism; var ares = new AutoResetEvent[threads]; var i = 0; var count = 0; Array.ForEach ( ares , (x) => { var are = new AutoResetEvent(false); ares[i++] = are; new Thread ( new ThreadStart ( () => { while (true) { int j = Interlocked.Increment(ref from); if (j <= to) { Interlocked.Increment(ref count); action(j); } else { break; } } are.Set(); } ) ).Start(); } ); WaitHandle.WaitAll(ares); Console.WriteLine(count); } } } |