Использование секундомера для измерения абстрактного метода во время выполнения - PullRequest
1 голос
/ 09 апреля 2011

Я хотел бы создать абстрактный класс с абстрактным методом, который может измерить, сколько времени потребуется для запуска.

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 и все же разрешать выполнение кода между ними?Могут ли события помочь мне здесь, если да, то как?

Ответы [ 2 ]

4 голосов
/ 09 апреля 2011

Использовать шаблон метода :

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

    protected abstract void DoRun();
}
1 голос
/ 09 апреля 2011

Вы можете просто сделать это так:

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 секунды.

...