2009-09-18 42 views
22

Làm thế nào để đóng dấu hai lần t1 và t2 và nhận được sự khác biệt trong mili giây trong C?Dấu thời gian bằng ngôn ngữ lập trình C

+5

Bạn không thể làm điều đó với tiêu chuẩn C một mình. Các giải pháp khả thi mà bạn có sẽ khác với Linux, Windows, điện thoại di động, máy tính tiền, ..., lò vi sóng, ... – pmg

+0

@Christoph: cả thời gian() và clock() có thể trả về -1 (truyền tới loại thích hợp) để biểu thị rằng hàm không có sẵn trong việc triển khai đó ... và thời gian(), khi có sẵn, có độ phân giải từ 1 giây trở xuống. Tôi đã sử dụng tiêu chuẩn nhưng không tìm thấy bất kỳ giới hạn cứng nào cho hàm clock() – pmg

+1

Trong trang hướng dẫn sử dụng Linux: "Lưu ý rằng thời gian có thể quấn quanh. Trên hệ thống 32 bit, nơi CLOCKS_PER_SEC bằng 1000000 chức năng này sẽ trả về cùng một giá trị cứ 72 phút một lần. " Để có được thời gian CPU getrusage() là tốt hơn, mặc dù đồng hồ là một phần của ANSI C, nhưng getrusage/gettimeofday() thì không. – user172818

Trả lời

28

này sẽ cung cấp cho bạn thời gian trong vài giây + micro

#include <sys/time.h> 
struct timeval tv; 
gettimeofday(&tv,NULL); 
tv.tv_sec // seconds 
tv.tv_usec // microseconds 
0

U có thể thử thói quen trong thời gian c thư viện (time.h). Ngoài ra, hãy xem clock() trong cùng một lib. Nó cung cấp cho các đồng hồ ve kể từ khi prog đã bắt đầu. Nhưng bạn có thể lưu giá trị của nó trước khi hoạt động bạn muốn tập trung vào, và sau đó sau đó hoạt động nắm bắt các ve khóa cliock một lần nữa và tìm thấy sự khác biệt giữa sau đó để có được sự khác biệt thời gian. đang

3

Sử dụng @Arkaitz Jimenez để nhận được hai timevals: Mã

#include <sys/time.h> 
//... 
struct timeval tv1, tv2, diff; 

// get the first time: 
gettimeofday(&tv1, NULL); 

// do whatever it is you want to time 
// ... 

// get the second time: 
gettimeofday(&tv2, NULL); 

// get the difference: 

int result = timeval_subtract(&diff, &tv1, &tv2); 

// the difference is storid in diff now. 

mẫu cho timeval_subtract có thể được tìm thấy tại this web site:

/* Subtract the `struct timeval' values X and Y, 
    storing the result in RESULT. 
    Return 1 if the difference is negative, otherwise 0. */ 

int 
timeval_subtract (result, x, y) 
     struct timeval *result, *x, *y; 
{ 
    /* Perform the carry for the later subtraction by updating y. */ 
    if (x->tv_usec < y->tv_usec) { 
    int nsec = (y->tv_usec - x->tv_usec)/1000000 + 1; 
    y->tv_usec -= 1000000 * nsec; 
    y->tv_sec += nsec; 
    } 
    if (x->tv_usec - y->tv_usec > 1000000) { 
    int nsec = (x->tv_usec - y->tv_usec)/1000000; 
    y->tv_usec += 1000000 * nsec; 
    y->tv_sec -= nsec; 
    } 

    /* Compute the time remaining to wait. 
     tv_usec is certainly positive. */ 
    result->tv_sec = x->tv_sec - y->tv_sec; 
    result->tv_usec = x->tv_usec - y->tv_usec; 

    /* Return 1 if result is negative. */ 
    return x->tv_sec < y->tv_sec; 
} 
+0

Mã trong timeval_subtract là ác vì nó sửa đổi giá trị đầu vào y. Nó sẽ không được xấu nếu các yếu tố đầu vào là hai giá trị struct timeval - như trái ngược với con trỏ. Nhưng khi đánh giá 'x - y', bạn thường không mong đợi tính toán thay đổi giá trị được lưu trữ trong 'y'. –

+0

@ Jonathan, đúng vậy. Mặc dù chỉ đơn giản là thay đổi nó thành một thực thi pass-by-copy sẽ giải quyết vấn đề đó – Glen

+0

Tôi đồng ý. Tôi sẽ sửa chữa nó, nhưng tôi không thể kiểm tra lại rằng những thay đổi của tôi sẽ được biên dịch vào lúc này, vì vậy tôi đã nghĩ rằng tôi sẽ để nó như vậy. – Bill

6

Nếu bạn muốn tìm thấy thời gian trôi qua, phương pháp này sẽ làm việc miễn là bạn không khởi động lại máy tính giữa đầu và cuối.

Trong Windows, sử dụng GetTickCount(). Đây là cách:

DWORD dwStart = GetTickCount(); 
... 
... process you want to measure elapsed time for 
... 
DWORD dwElapsed = GetTickCount() - dwStart; 

dwElapsed tại là số mili giây trôi qua.

Trong Linux, sử dụng đồng hồ()CLOCKS_PER_SEC để thực hiện tương tự.

Nếu bạn cần dấu thời gian kéo dài thông qua khởi động lại hoặc trên máy tính (cần đồng bộ hóa khá tốt), thì hãy sử dụng các phương thức khác (gettimeofday()).

Ngoài ra, trong Windows ít nhất bạn có thể nhận được tốt hơn nhiều so với độ phân giải thời gian chuẩn. Thông thường, nếu bạn gọi GetTickCount() trong một vòng lặp chặt chẽ, bạn sẽ thấy nó nhảy 10-50 mỗi lần nó thay đổi. Đó là do lượng tử thời gian được sử dụng bởi bộ lập lịch trình chuỗi Windows. Đây là nhiều hơn hoặc ít hơn số lượng thời gian nó cho mỗi thread chạy trước khi chuyển sang cái gì khác. Nếu bạn làm một:

timeBeginPeriod(1); 

vào đầu chương trình của bạn hay quy trình và a:

timeEndPeriod(1); 

ở cuối, sau đó các lượng tử sẽ thay đổi tới 1 ms, và bạn sẽ nhận được thời gian tốt hơn nhiều độ phân giải trên cuộc gọi GetTickCount(). Tuy nhiên, điều này thực hiện một sự thay đổi tinh tế về cách toàn bộ máy tính của bạn chạy các tiến trình, vì vậy hãy ghi nhớ điều đó. Tuy nhiên, Windows Media Player và nhiều thứ khác làm điều này thường xuyên, vì vậy tôi không lo lắng quá nhiều về nó. Tôi chắc chắn có một số cách để làm tương tự trong Linux (có thể với kiểm soát tốt hơn nhiều, hoặc có thể với lượng tử tiểu phần nghìn giây) nhưng tôi không cần phải làm điều đó trong Linux.

8

Chuẩn C99:

#include <time.h> 

time_t t0 = time(0); 
// ... 
time_t t1 = time(0); 
double datetime_diff_ms = difftime(t1, t0) * 1000.; 

clock_t c0 = clock(); 
// ... 
clock_t c1 = clock(); 
double runtime_diff_ms = (c1 - c0) * 1000./CLOCKS_PER_SEC; 

Độ chính xác của các loại là thực hiện xác định, tức là sự khác biệt datetime chỉ có thể trở lại đầy đủ giây.

+0

Sự khác biệt về thời gian datetime trả về đầy đủ giây ở mức tốt nhất. Nếu tôi diễn giải chuẩn một cách chính xác, time(), khi nó không trả về (time_t) -1, không đảm bảo trả về giá trị mới mỗi giây: nó có thể có độ phân giải 5 giây hoặc 1 phút chẳng hạn. – pmg

+2

@pmg: độ chính xác được triển khai, ví dụ: trên hệ thống 'time()' có độ phân giải '1s'; độ chính xác của 'clock()' thường cao nhất có thể, nhưng nó đo thời gian chạy và không phải datetime – Christoph

1

Cũng biết về tương tác giữa đồng hồ() và usleep(). usleep() đình chỉ chương trình, và clock() chỉ đo thời gian chương trình đang chạy.

Nếu có thể được tốt hơn để sử dụng gettimeofday() như đã đề cập here

5
/* 
Returns the current time. 
*/ 

char *time_stamp(){ 

char *timestamp = (char *)malloc(sizeof(char) * 16); 
time_t ltime; 
ltime=time(NULL); 
struct tm *tm; 
tm=localtime(&ltime); 

sprintf(timestamp,"%04d%02d%02d%02d%02d%02d", tm->tm_year+1900, tm->tm_mon, 
    tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); 
return timestamp; 
} 


int main(){ 

printf(" Timestamp: %s\n",time_stamp()); 
return 0; 

} 

Output: Timestamp: 20110912130940 // 2011 Sep 12 13:09:40

+0

Thay vì định dạng dữ liệu, bạn có thể sử dụng asctime (tm) trả về một chuỗi. –

2

thế nào về giải pháp này? Tôi không thấy bất cứ điều gì như thế này trong tìm kiếm của tôi. Tôi đang cố tránh phân chia và làm cho giải pháp đơn giản hơn.

struct timeval cur_time1, cur_time2, tdiff; 

    gettimeofday(&cur_time1,NULL); 
    sleep(1); 
    gettimeofday(&cur_time2,NULL); 

    tdiff.tv_sec = cur_time2.tv_sec - cur_time1.tv_sec; 
    tdiff.tv_usec = cur_time2.tv_usec + (1000000 - cur_time1.tv_usec); 

    while(tdiff.tv_usec > 1000000) 
    { 
     tdiff.tv_sec++; 
     tdiff.tv_usec -= 1000000; 
     printf("updated tdiff tv_sec:%ld tv_usec:%ld\n",tdiff.tv_sec, tdiff.tv_usec); 
    } 

    printf("end tdiff tv_sec:%ld tv_usec:%ld\n",tdiff.tv_sec, tdiff.tv_usec); 
Các vấn đề liên quan