[C#]mierzenie czasu wykonywania algorytmu


(Gkuczmik89) #1

Mam problem chcę pomierzyć czas wykonywania algorytmu. Piszę aplikacje w C#

W klasie rozwiązującej mam zdefiniowane pola DateTime start, DateTime end;

w metodzie obsługującej algorytm mam :

public string jakisAlgorytm()

{

start = DateTime.Now;

blok algorytmu ...

end = DataTime.Now;

return wynik;

}

tam gdzie chce mieć to policzone robię (gdzie wywołuje metodę algorytm):

TimeSpan ts = klasa.end - Klasa.start;

double czas = ts.Milliseconds;

Problem jest taki, że czas jest 0. Najśmieszniejsze jest to że gdy debuguje i mam 2 breakpointy ustawione na start i end to pobierany jest dobrze czas i działa ale jak uruchamiam bez to zawsze jest 0.


(Tomek Matz) #2

Powinno działać, choć podmień

double czas = ts.Milliseconds;

(skąd pomysł, żeby rzutować w tym przypadku int na typ zmiennoprzecinkowy?), na

int czas = ts.Milliseconds;

Żeby wyświetlić TimeSpan użyj metody ToString() lub którejś z jej przeciążonych wersji, np. ToString(string format).


(Gkuczmik89) #3

a czemu miałby tu służyć dodatkowy wątek ? chyba da się mierzyć czas wykonywania kodu w głównym wątku

podmieniłem na int dalej 0


(Drobok) #4

System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();

//kod

sw.Stop();

sw.Elapsed.Ticks; //zmienna z czasem


(Tomek Matz) #5

Mógłbyś podać jakie czasy masz dla pól start i end? Może da się ustalić, czemu dla właściwości Milliseconds zawsze masz 0.

I jeszcze jedno ... Jeśli chcesz dokładnie odczytać wartość TimeSpan, to lepiej użyć właściwości Ticks (typu long).


(Gkuczmik89) #6

dzięki twoje rozwiązanie działa teraz dobrze


(CzoQś) #7

public string jakisAlgorytm()

{

double start = DateTime.Now.Ticks;

blok algorytmu ...

double end = ((DateTime.Now.Ticks - start) / 10000000); //wynik w sekundach

MessageBox.Show("time = " + Math.Round(end,2) + " s"); //Wyświetla wynik w okienku

return wynik;

}


(Tomek Matz) #8

@CzoQś

Ticks jest typu long, a Ty rzutujesz go na typ double - czemu?. Niech pola start i end będą typu DateTime. Jeśli chciałbyś uzyskać wynik w sekundach, to można zrobić wówczas TimeSpan duration = end - start; i z właściwości duration.TotalSeconds odczytać liczbę wszystkich sekund, które upłynęły pomiędzy start i end. Jeśli zajdzie taka potrzeba, to przed wyświetleniem wyniku na ekranie, zaokrąglisz go jeszcze do odpowiedniej liczby miejsc po przecinku.


(somekind) #9

Sugeruję przestać próbować jeść zupę nożem i widelcem.

Poprawne rozwiązanie podał już drobok i nie ma co filozofować. DateTime nie służy do mierzenia czasu wykonywania algorytmu, od tego jest Stopwatch.


(Tomek Matz) #10

Nikt przecież tutaj nie pisał, że DateTime służy do mierzenia czasu. Pola end i start są po to, aby wiedzieć kiedy dokładnie rozpoczęło i zakończyło się przetwarzanie. W jaki sposób można te dane uzyskać z obiektu klasy StopWatch?


(CzoQś) #11

Rzutowanie na double, aby zaokrąglić do 2 miejsc po przecinku - wymaga typu double więc zaraz na początku dałem...

Oczywiście powinno być na long...


(somekind) #12

Ale po co je uzyskiwać? Temat dotyczy przecież mierzenia czasu wykonania algorytmu, nieprawdaż?

Wiesz w ogóle, co to jest double, long i na czym polega zaokrąglanie? Bo chyba coś Ci nie wyszło z tym postem.


(CzoQś) #13

Moją intencją było zwrócenie komunikatu o czasie wykonywania algorytmu - format sekundowy z 2 miejscami po przecinku...

Zapewne orientujesz się, że zaokrąglanie Round odbywa się na liczbach typu double - więc od samego początku użyte zostały takie typy dla start/end...ot i cała filozofia.

Oczywiście można było dać start/end jako long, ale później przy zaokrąglaniu trzeba rzutować i tak na double...wybrałem 1 z 2 możliwości - co w tym niezrozumiałego dla Ciebie?

A czy Ty "Wiesz w ogóle, co to jest double, long i na czym polega zaokrąglanie?"?

:slight_smile: Pozdrawiam


(somekind) #14

Jakby nie patrzeć, czym innym jest zaokrąglanie, a czym innym wyświetlanie z dokładnością, warto nauczyć się odróżniać te dwie rzeczy.

Niezrozumiałe dla mnie jest utrudnianie sobie życia i kombinowanie, zamiast zrobienia czegoś porządnie. Dlaczego chcesz cudować w taki zagmatwany sposób, zamiast po prostu wyświetlić TimeSpan w odpowiednim formacie?

using System;

using System.Threading;


namespace ConsoleApplication26

{

    class Program

    {

        static void Main(string[] args)

        {

            DateTime start = DateTime.Now;

            Thread.Sleep(new Random().Next(1000, 5000)); // udawany algorytm

            DateTime stop = DateTime.Now;


            TimeSpan diff = stop - start;


            Console.WriteLine(diff.ToString("ss\\,ff"));

        }

    }

}

Oczywiście to przy założeniu, że chcemy się posługiwać DateTime, a w przypadku "problemu" z tego wątku nie mamy po co.

Jak widać, wiem "trochę" więcej od Ciebie. ;]