برای تشخیص زمان اجرای یک برنامه می بایست از قابلیت فراخوانی توابع محلی بهره بگیرید. دو تابع ANSI C در فایل هدر time.h تعریف شده اند که برای این منظور به کار می روند:
- clock_t clock();
- time_t time(time_t *tptr);
تابع time() تعداد ثانیه هایی که از مبدا زمانی رخ داده است را بر می گرداند. مبدا زمانی یک نقطه مرجع زمانی دلخواه است که در اکثر مراجع 1 ژانویه 1970 میلادی ( یعنی زمان 00:00:00 ) در نظر گرفته می شود. مشکلی که راجع به تابع time() وجود دارد این است که تابع مذکور با واحد های زمانی ای کار می کند که گسستگی مناسب و کافی را ندارند. لازم به ذکر است که اکثر رویدادهای مهم یک برنامه در بازه های زمانی ای به اندازه ی میلی ثانیه، میکرو ثانیه و یا نانو ثانیه رخ می دهند.
تابع clock() تعداد تیک های ساعت سیستم از زمانی که یک فرآیند شروع شده است را برمی گرداند.تعداد تیک ها در ثانیه توسط ماکروی CLOCKS_PER_SEC تعریف می گردد که این مقدار در سخت افزار های مختلف اندازه ای متفاوت دارد. ببینیم که چگونه این مقدار به پردازنده بستگی پیدا می کند.Win32 API یک روتین به نام GetTickCount() فراهم کرده است که تعداد میلی ثانیه هایی که از زمان بارگذاری سیستم عامل گذشته را برمی گرداند.تصمیم دارم که از این تابع برای محاسبه زمان اجرای کد خود استفاده کنم.
اگر شما علاقمند باشید که کدهای قابل حمل[1] بنویسید، ممکن است بخواهید از تابع clock() استفاده کنید.
در اینجا یک مثال کوتاه اورده شده تا نشان داده شود که این سه تابع درعمل چگونه مورد استفاده قرار می گیرند:
/* --ansiTime.c-- */
#include<stdio.h>
#include<time.h>
#include<windows.h>
void main()
{
unsigned long i;
time_t t1,t2;
clock_t ticks1,ticks2, dt;
unsigned long msec1,msec2;
time(&t1);
ticks1 = clock();
msec1 = GetTickCount();
/*do some work*/
for(i=0;i<0xFFFFFFFF;i++){}
time(&t2);
ticks2 = clock();
msec2 = GetTickCount();
printf("number of elapsed seconds = %lu\n",t2-t1);
dt = ticks2-ticks1;
printf("number of clock ticks = %lu\n",dt);
printf("ticks/second = %lu\n",CLOCKS_PER_SEC);
printf("number of elapsed seconds = %lu\n",
dt/CLOCKS_PER_SEC);
printf("msecs=%lu\n",msec2-msec1);
return;
}/* --ansiTime.c-- */
#include<stdio.h>
#include<time.h>
#include<windows.h>
void main()
{
unsigned long i;
time_t t1,t2;
clock_t ticks1,ticks2, dt;
unsigned long msec1,msec2;
time(&t1);
ticks1 = clock();
msec1 = GetTickCount();
/*do some work*/
for(i=0;i<0xFFFFFFFF;i++){}
time(&t2);
ticks2 = clock();
msec2 = GetTickCount();
printf("number of elapsed seconds = %lu\n",t2-t1);
dt = ticks2-ticks1;
printf("number of clock ticks = %lu\n",dt);
printf("ticks/second = %lu\n",CLOCKS_PER_SEC);
printf("number of elapsed seconds = %lu\n",
dt/CLOCKS_PER_SEC);
printf("msecs=%lu\n",msec2-msec1);
return;
}
اگر این برنامه ساخته و اجرا شود، خروجی هایی از نوع زیر تولید می کند:
number of elapsed seconds = 31
number of clock ticks = 30980
ticks/second = 1000
number of elapsed seconds = 30
msecs=30960
پراکندگی و توزیع داده ها:ساختن مقادیر مختلف و تصادفی
برای تست برنامه مدیریت حافظه دستی نوشته شده، نیاز است که یک سری طولانی از تخصیص و آزاد سازی را در مورد آن انجام دهم. طبیعی است که به سادگی نمی توانم بلوک های حافظه ای که همه دارای اندازه یکسان هستند را تخصیص دهم.
#include<stdlib.h>
void main()
{
unsigned int i,j;
unsigned int nblocks;
unsigned int nbytes;
unsigned char* ptrs[1024];
nbytes=4096;
nblocks=1024;
for(i=0;i<nblocks;i++)
{
ptrs[i]=malloc(nbytes);
for(j=0;j<nbytes;j++)
{
char *cptr;
cptr = ptrs[i];
cptr[j] = 'a';
}
}
for(i=0;i<nblocks;i++)
{
free (ptrs[i]);
}
return;
برنامه ی قبل یک مدیریت کننده حافظه را مجبور نمی کرد تا با درخواست های دلخواهی که یک مدیریت کننده هیپ با آن مواجه می شود، سروکار داشته باشد. از طرف دیگر، یک سری کاملا تصادفی از تخصیص ها نیز در عمل خیلی واقعی به نظر نمی رسد.
#include<stdlib.h>
void main()
{
unsigned int i,j;
unsigned int nblocks;
unsigned int nbytes;
unsigned char* ptrs[1024];
nblocks=1024;
for(i=0;i<nblocks;i++)
{
nbytes=rand();
ptrs[i]=malloc(nbytes);
for(j=0;j<nbytes;j++)
{