使用秒表测量抽象方法的运行时间

本文关键字:抽象方法 运行时间 测量 | 更新日期: 2023-09-27 17:49:45

我想用一个抽象方法创建一个抽象类,它可以测量运行需要多长时间。

public abstract class Monitor
{
    protected Stopwatch Timer = Stopwatch.StartNew();   
    public abstract void Run();
}
public class Concrete : Monitor
{
    public override void Run()
    {
        base.Timer.Start();
        //DoSomething
        base.Timer.Stop();
    }
}

但是,抽象类的实现者不应该直接调用Start/Stop方法,因此我们可以尝试隐藏实现。

public abstract class Monitor
{
    private Stopwatch Timer = Stopwatch.StartNew(); 
    public virtual void Run()
        {
            Timer.Start();
            Timer.Stop();
        }
}

但是正如你所看到的,这不会很好地工作。

我如何确保基类的所有实现都将调用Start/Stop并允许实现代码在两者之间运行?这里的事件能帮到我吗,如果能,又是怎样的呢?

使用秒表测量抽象方法的运行时间

使用模板方法:

public abstract class Monitor
{
    private readonly Stopwatch Timer = new Stopwatch(); 
    public void Run()
    {
        Timer.Start();
        DoRun();
        Timer.Stop();
    }
    protected abstract void DoRun();
}

你可以这样做:

public abstract class Monitor
{
    protected Stopwatch Timer = Stopwatch.StartNew();   
    public abstract void Run();
    public void Test()
    {
        Timer.Start();
        Run();
        Timer.End();
    }
}
public class Concrete : Monitor
{
    public override void Run()
    {
        //DoSomething
    }
}

这里有虚调用的开销,但它应该很小。为了减少成本,你可以先做一些热身电话,然后再做实际的计时电话。这也有让JIT运行并进行优化的好处。例如:

public abstract class Monitor
{
    protected Stopwatch Timer = Stopwatch.StartNew();   
    public abstract void Run();
    public void Test()
    {
        // Warm up to let JIT do it's magic.
        for (int i = 0; i < 1000; i++)
            Run();
        Timer.Start();
        Run();
        Timer.End();
    }
}

我记得不久前在一个回答中读到,你应该尝试做至少1到1.5秒的循环你想要基准的函数。