Как измерить, как долго работает функция?

Я хочу посмотреть, как долго функция работает. Поэтому я добавил объект timer в свою форму, и я вышел с этим кодом:

private int counter = 0;

// Inside button click I have:
timer = new Timer();
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
Result result = new Result();
result = new GeneticAlgorithms().TabuSearch(parametersTabu, functia);
timer.Stop();

и:

private void timer_Tick(object sender, EventArgs e)
{
    counter++;
    btnTabuSearch.Text = counter.ToString();
}

но это ничего не считая. Почему?

10 ответов


чтобы избежать будущих проблем с таймером, вот правильный код:

timer = new Timer();
timer.Tick += new EventHandler(timer_Tick);
timer.Interval = 1; //set interval on 1 milliseconds
timer.Enabled = true; //start the timer
Result result = new Result();
result = new GeneticAlgorithms().TabuSearch(parametersTabu, functia);
timer.Enabled = false; //stop the timer

private void timer_Tick(object sender, EventArgs e)
{
   counter++;
   btnTabuSearch.Text = counter.ToString();
}

но это неправильный подход. Вы должны использовать Секундомер (Система.Диагностика) класс, потому что это таймер высокого разрешения и слово Диагностика все сказано.

Так что попробуйте это:

Stopwatch timer = Stopwatch.StartNew();

Result result = new Result();
result = new GeneticAlgorithms().TabuSearch(parametersTabu, functia);

timer.Stop();  
TimeSpan timespan = timer.Elapsed;

btnTabuSearch.Text = String.Format("{0:00}:{1:00}:{2:00}", timespan.Minutes, timespan.Seconds, timespan.Milliseconds / 10);

Не используйте таймер-используйте Stopwatch класса.

var sw = new Stopwatch();
Result result = new Result();

sw.Start();
result = new GeneticAlgorithms().TabuSearch(parametersTabu, functia);

sw.Stop();

// sw.Elapsed tells you how much time passed

вы должны использовать класс Stopwatch для функции времени.

попробуйте следующее:

private int counter = 0;

// setup stopwatch and begin timing
var timer = System.Diagnostics.Stopwatch.StartNew();

Result result = new Result();
result = new GeneticAlgorithms().TabuSearch(parametersTabu, functia);

// stop timer and get elapsed time
timer.Stop();
var elapsed = timer.Elapsed;

// display result time
MessageBox.Show(elapsed.ToString("mm':'ss':'fff"));

лучший способ увидеть, сколько кода требуется для запуска использовать System.Diagnostics.Stopwatch.

вот пример:

using System.Diagnostics;

#if DEBUG
     Stopwatch timer = new Stopwatch();
     timer.Start();
#endif

     //Long running code

#if DEBUG
     timer.Stop();
     Debug.WriteLine("Time Taken: " + timer.Elapsed.TotalMilliseconds.ToString("#,##0.00 'milliseconds'"));
#endif

Я использую #if DEBUG чтобы код секундомера не попал в производственный выпуск, но вы могли бы обойтись без него.


Visual Studio 2015 2017, Professional и Enterprise имеет диагностический инструмент. Если у вас есть точка останова в конце вашей функции, она отобразит время и продолжительность под событий вкладка, как показано на рисунке:

Enter image description here

вы можете увидеть статью окно отладчика диагностических средств в Visual Studio 2015 для получения более подробной информации.

PS; пока только Xamarin формы, крест проект платформы не поддерживает эту функцию. Я хочу, чтобы Microsoft принесла эту замечательную функцию и для проектов xamarin forms.


использовать секундомер системы.Диагностика:

static void Main(string[] args)
{
    Stopwatch stopWatch = new Stopwatch();
    stopWatch.Start();
    Thread.Sleep(10000);
    stopWatch.Stop();

    // Get the elapsed time as a TimeSpan value.
    TimeSpan ts = stopWatch.Elapsed;

    // Format and display the TimeSpan value.
    string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
        ts.Hours, ts.Minutes, ts.Seconds,
        ts.Milliseconds / 10);
    Console.WriteLine("RunTime " + elapsedTime);
}

для синхронизации функции, вы должны использовать Секундомер Класс

кроме того, ваш таймер не подсчитывает, потому что вы не установили интервал для него.


возможно, вы могли бы написать метод, как это:

public static void Time(Action action)
{
    Stopwatch st = new Stopwatch();
    st.Start();
    action();
    st.Stop();
    Trace.WriteLine("Duration:" + st.Elapsed.ToString("mm\:ss\.ff"));
}

и используйте его так:

Time(()=>
{
 CallOfTheMethodIWantToMeasure();
});

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

основная причина не реализовывать logger в общем виде - выполнение метода находится между секундомером.Start() и секундомер.Stop() также нам может потребоваться результат метода после выполнения для дальнейшего обработка.

поэтому для решения этой проблемы я создал следующий пример реализации, где время выполнения регистрируется отдельно, не смешивая его с фактическим потоком метода.

public static class Helper
{
    public static T Time<T>(Func<T> method, ILogger log)
    {
        var stopwatch = new Stopwatch();
        stopwatch.Start();
        var result = method();
        stopwatch.Stop();
        log.Info(string.Format("Time Taken For Execution is:{0}", stopwatch.Elapsed.TotalMilliseconds));
        return result;
    }
}

public class Arithmatic
{
    private ILogger _log;
    public Arithmatic(ILogger log)//Inject Dependency
    {
        _log = log;
    }

    public void Calculate(int a, int b)
    {
        try
        {
            Console.WriteLine(Helper.Time(() => AddNumber(a, b), _log));//Return the result and do execution time logging
            Console.WriteLine(Helper.Time(() => SubtractNumber(a, b), _log));//Return the result and do execution time logging
        }
        catch (Exception ex)
        {
            _log.Error(ex.Message, ex);
        }
    }

    private string AddNumber(int a, int b)
    {
        return "Sum is:" + (a + b);
    }

    private string SubtractNumber(int a, int b)
    {
        return "Subtraction is:" + (a - b);
    }
}

public class Log : ILogger
{
    public void Info(string message)
    {
        Console.WriteLine(message);
    }

    public void Error(string message, Exception ex)
    {
        Console.WriteLine("Error Message:" + message, "Stacktrace:" + ex.StackTrace);
    }
}

public interface ILogger
{
    void Info(string message);
    void Error(string message, Exception ex);
}

Называя Части:

 static void Main()
 {
    ILogger log = new Log();
    Arithmatic obj = new Arithmatic(log);
    obj.Calculate(10, 3);
    Console.ReadLine();
 }

запишите время, когда текущий шаг начинает обрабатывать

DateTime dtStart = DateTime.Now;

//Calculate the total number of milliseconds request took (Timespan = to represent the time interval)-> current - started time stamp ...
//TotalMilliseconds -->Gets the value of the current TimeSpan structure expressed in whole and fractional milliseconds.
// to measure how long a function is running 
var result=((TimeSpan)(DateTime.Now - dtStart)).TotalMilliseconds.ToString("#,##0.00") + "ms";