c# 统计方法执行时间,计算缓存读取数据方法的命中率

  一.              构造StopwatchPool

 

System.Diagnostics命名空间中dot net framework为我们提供了精确计算代码执行时间的类Stopwatch;因为我们可能频繁使用Stopwatch类的实例,所以我们在此做一个简单的对象池,尽量降低非方法执行时间对程序性能的影响。

 

StopwatchPool类的静态字段List<StopwatchWithUseState> _watchList中包含了系统中初始化好的StopwatchWithUseState实例;StopwatchWithUseState 实例中是Stopwatch的实例,和一个它是否正在被使用的字段。当需要新的Stopwatch实例使直接调用StopwatchPool的静态方法NewStopwatch()即可,注意在使用完Stopwatch实例之后需要调用ReleaseWatch(Stopwatch)释放掉Stopwatch。具体代码会在文章结尾给出,其类图如下:

二.              统计方法执行时间

 

类图如下:

MethodPerfMonitor 的关键实现是在进入一个方法时执行 EnterMethod() 方法,该方法会申请一个 Stopwatch 实例,并启动实例,记录方法执行次数;在方法执行结束时调用 FinishMethod() 方法,记录方法执行时间,并释放 Stopwatch 实例。其关键代码如下
/**/ /// <summary>
        
/// 在方法开始执行时调用此方法
        
/// </summary>

        [Conditional(EnablePerfMonitor.CompilerSymbal)]
        
public   virtual   void  EnterMethod()
        
{
            
lock (instanceLock)
            
{
                _execCount
++;
                
if (_startRunTime == DateTime.MinValue)
                
{
                    _startRunTime 
= DateTime.Now;
                }

            }

            _watch 
= StopwatchPool.NewStopwatch();
            _watch.Start();
        }



        
/**/ /// <summary>
        
/// 在方法完成之前调用,必须调用,若不调用会导致申请的Stopwatch得不到释放
        
/// 最好在try{}finally{}的finally中释放
        
/// </summary>

        [Conditional(EnablePerfMonitor.CompilerSymbal)]
        
public   virtual   void  FinishMethod()
        
{
            
lock (instanceLock)
            
{
                TotalRunTime 
+= TimeSpan.FromTicks(_watch.ElapsedTicks);
            }

            StopwatchPool.ReleaseWatch(_watch);
        }

大家可以看到在两个方法的前面都使用了 Conditional 特性,这样可以在编译时方便的启用或者禁用方法执行时间统计。

在这个类中还提供了一个静态方法RegisterMonitor(string methodFullName)这个方法会返回一个MethodPerfMonitor类的实例,若该类的静态字段_methodMonitorTable中有方法全名对应的MethodPerfMonitor实例,则直接返回,否则将新生成的实例保存在该类的一个静态字段中。这样保证一个实例对应一个方法的统计。

 

三.              统计缓存方法的执行时间和缓存命中率

 

我们需要一个新的类来统计方法的缓存命中情况,CachableMethodPerfMonitor该类从MethodPerfMonitor继承,该类只多了一个功能统计缓存的命中率;在方法执行结束时执行FinishMethod时需要指定这一次执行是否命中了缓存。并添加方法执行时间和缓存命中时的执行时间。其关键实现如下:

/**/ /// <summary>
        
/// 在方法结束时调用
        
/// </summary>
        
/// <param name="isHitCache">是否命中缓存</param>

        [Conditional(EnablePerfMonitor.CompilerSymbal)]
        
public   void  FinishMethod( bool  isHitCache)
        
{
            
lock (instanceLock)
            
{
                TimeSpan execTimespan 
= TimeSpan.FromTicks(_watch.ElapsedTicks);
                
if (isHitCache)
                
{
                    CacheRunTime 
+= execTimespan;
                    _hitTimes
++;
                }

                TotalRunTime 
+= execTimespan;
            }


            StopwatchPool.ReleaseWatch(_watch);
        }

四.              如何使用

 

请看如下实例代码。有问题欢迎提出。

相关源码下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值