Szeretném egy programrészlet futásidejét mérni (másodpercben). A következőket próbáltam:
clock_t t1=clock();
...
egyéb utasítások
...
clock_t t2=clock();
masodperc=(t2-t1)/CLOCKS_PER_SEC;
A probléma az, hogy a t1, t2 csak long értéket (úgy tudom, hogy clock_t is long(?), ill. a clock() long-al tér vissza) hajlandó elfogadni, amivel nem sokra megyek, mert nem tudok vele osztani legalábbis nekem nem ad tizedestörtet az itt is látható kódrészlet utolsó sora, ill. ha 1-nél kisebb, 0-nak veszi. Több helyen láttam kényszerített típuskonverziós megoldásokat, mint pl:
masodperc=((double)(t2-t1))/CLOCKS_PER_SEC;
vagy:
masodperc=((double)(t2-t1)/CLOCKS_PER_SEC);
de nekem nem működtek, ill. ha ezek nélkül próbéltam akkor a már leírt jelenséget muatta, ezzel pedig (ebben az esetben a "masodperc" változó értelemszerűen double) lehetetlen (pl. negatív) értékeket adott.
Van esetleg valakinek ötlete, mi lehet a hiba?
- 972 megtekintés
Hozzászólások
nyos@nyos:~/src$ cat idoeltelik.c
#include <time.h>
#define N 30000
main()
{
clock_t t0,t1;
int i,j,k;
double ido;
t0=clock();
/////////////// csinalunk valamit /////////////
for(i=0;i<N;i++)
for(j=0;j<N;j++)
if(i<j)
k++;
///////////////////////////////////////////////
t1=clock();
ido=t1-t0;
ido/=CLOCKS_PER_SEC;
printf("%ld - %ld\n",t0,t1);
printf("%lf\n",ido);
printf("%lf\n",((double)(t1-t0))/CLOCKS_PER_SEC);
}
nyos@nyos:~/src$ time ./a.out
0 - 2220000
2.220000
2.220000
real 0m2.250s
user 0m2.228s
sys 0m0.004s
Gyakorlatilag 1:1-ben a te kodod, es nalam mukodik..
Milyen nagysagrendu az, amit mersz?
Ha tul kicsi, nem jo. Ez csak egy kozelitest ad.
Ha tul nagy (mondjuk 20-30 perc), az alatt a 32 bites szam korbefordulhat, es igy negativ szamot kapsz (a leirasa szerint 72 percenkent ugyanazt adja vissza).
Elobbi esetben probald meg a merendo kodot tobbszor lefuttatni egy ciklusban, hogy pontosabb eredmenyt kapj.
Utobbi esetben inkabb time-al inditsd el, es szedd ki a tobbi, lassito kodot a programodbol (bar ha csak azt akarod merni, akkor nem sokat szamit az inicializalas, csak a fo szamitas ideje).
Hasznos lehet meg a gnu profiler hasznalata.
gcc -pg opcioval kell forditani, utana a gprof-al elemezni
Kiirja, hogy melyik fuggvenyek hanyszor futottak le, atlagosan, es osszesen, illetve szazalekban melyik mennyi processzoridot igenyelt.
Ugyanezt kulon es rekurzivan is kiszamolja. (Egyik esetben a main-ben tolti a program az ido 100%-at, hiszen fut. Masik esetben csak amig tenylegesen a main-en van a vezerles.)
---------------------
int iPhone,iMac,iPod; // Apple using Hungarian notation :)
- A hozzászóláshoz be kell jelentkezni
Köszönöm
Nem kell túl nagy pontosság. A legkisebb érték, amit mérni akarok, az kb. 0.05s. Ha pontossága +/- 0.005-ön belül van, az már jó.
Szerk.: most végre működik, de hogy mitől...? :) Egyébként egy gcc paraméterre gyanakszom (-O2), de nem vagyok biztos benne...
- A hozzászóláshoz be kell jelentkezni
Nincs köze a jelen problémához, de esetleg érdemes lehet 'long long' típusban tartani a t1 és t2 értékeket.
Addig, amig csak kivonod őket egymásból, természetesen nincsen semmi baj, de ha mondjuk ki akarod írni a (printf) az értékeket, akkor máris fogalmad sincs hogy azon a gépen, ahol majd a programot valaki valamikor fordítani akarja, '%lu' '%llu' vagy valami más lesz-e a megfelelő szekvencia.
- A hozzászóláshoz be kell jelentkezni
Szerintem ha pontosabb ido"ziteseket es/vagy ido"intervallum-me're'seket csinalna'l, akkor ne a
clock()
-ot hasznald, hanem a
getrusage()
es/vagy
gettimeofday()
fuggvenyeket. Ezeknel tuti nem jon elo" az a hiba, hogy a visszateresi ertek (clock_t) platform-fuggo" legyen, illetve tulcsordulas sem lesz (ti. a clock() az kb. 72-73 perces periodussal ugyanazt az erteket adja vissza, tehat ha ennel hosszabb intervallumot akarsz me'rni, akkor a clock() semmikeppen sem lesz jo.
En erre csinaltam egy p'ar egyszerubb fv-t:
double get_user_time(void)
{
struct rusage ru;
double tm;
getrusage(RUSAGE_SELF,&ru);
tm=(double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec/1000000.0;
return(tm);
}
double get_real_time(void)
{
struct timeval tv;
double tm;
gettimeofday(&tv,NULL);
tm=(double)tv.tv_sec+(double)tv.tv_usec/1000000.0;
return(tm);
}
primko', de a celnak teljesen jol megfelel.
A.
- A hozzászóláshoz be kell jelentkezni