اندازه گیری زمان اجرا

farzaneh0

New Member
با سلام
آقا خواهش می کنم محض رضای خدا یکی کمکم کنه من چند وقت است می خواهم زمان اجرای برنامه ام را با کد زیر اندازه گیری کنم ولی همش زمان صفر را می ده باور کنید حتی برنامه ام را 200 بار فراخوانی کرده ام تا زمانش طولانی شود ولی نتیجه ای نداشته کمکم کنید
clock_t begin,end;
begin=clock();
برنامه ای که می خوام زمان آن را اندازه گیری کنم
end=clock();
d=((end-begin)*1000)/CLOCKS_PER_SEC;
cout<<d
 

the_king

مدیرکل انجمن
با سلام
آقا خواهش می کنم محض رضای خدا یکی کمکم کنه من چند وقت است می خواهم زمان اجرای برنامه ام را با کد زیر اندازه گیری کنم ولی همش زمان صفر را می ده باور کنید حتی برنامه ام را 200 بار فراخوانی کرده ام تا زمانش طولانی شود ولی نتیجه ای نداشته کمکم کنید
clock_t begin,end;
begin=clock();
برنامه ای که می خوام زمان آن را اندازه گیری کنم
end=clock();
d=((end-begin)*1000)/CLOCKS_PER_SEC;
cout<<d

فرض های مساله :
توابع ()MyFunction1 و ()MyFunction2 توابعی هستند که قصد مقایسه کردن سرعت اجرایشان را دارید.
زمانی که برای اجرا های متوالی هر کدام از ایندو تابع صرف خواهید کرد (بر حسب ثانیه ) را t می نامیم که در کد مثال
5 ثانیه خواهد بود.
تابع ()round برای محاسبه کردن عملیات ریاضی گرد کردن عدد اعشاری به نزدیکترین عدد صحیح بدون اعشار بکار می رود.
تابع ()CompareResults بر اساس تعداد اجرا های تو تابع در طی زمان t و حذف کردن تغییرات کوچکی که ممکن است
در هر بار اجرا تغییر کنند، تابع برنده (سرعت اجرای بیشتر) و میزان درصدی که سرعتش از تابع بازنده بیشتر
است را بر می گرداند.

کد:
#include <iostream>
#include <math.h>

using namespace std;

const clock_t t = 5;

double round(double x)
{
    double n = floor(x);
    double m = ceil(x);
    return (fabs(x - n) < fabs(x - m)) ? n : m;
}

void CompareResults(long count1, long count2, long *percent, int *winner)
{
    double factor;
    if (count1 < count2)
    {
        factor = ((double)count2 / (double)count1 - 1) * 100;
        *winner = 2;
    }
    else
    {
        factor = ((double)count1 / (double)count2 - 1) * 100;
        *winner = 1;
    }
    if (factor < 100)
    {
        *percent = 0;
        *winner = 0;
    }
    else
    {
        long base = (long)round(pow(10, floor(log10(factor))));
        *percent = (long)(round((double)factor / base) * base);
    }
}

long MyFunction1()
{
    long sum = 0;
    for (int i = 1; i <= 1000; i++)
        sum += i;
    return sum;
}

long MyFunction2()
{
    long sum = (1000 + 1) * (1000 / 2);
    return sum;
}

int main()
{
    clock_t end;
    long count1 = 0, count2 = 0;
    cout << "Please wait...it take " << t << " seconds." << endl;
    end = clock() + CLOCKS_PER_SEC * t;
    while (clock() < end)
    {
        MyFunction1();
        count1++;
    }
    cout << "Please wait...it take " << t << " seconds." << endl;
    end = clock() + CLOCKS_PER_SEC * t;
    while (clock() < end)
    {
        MyFunction2();
        count2++;
    }
    int winner;
    long percent;
    CompareResults(count1, count2, &percent, &winner);
    switch (winner)
    {
        case 1 :
            cout << "MyFunction1 is " << percent << "% faster than Myfunction2." << endl;
            break;
        case 2 :
            cout << "MyFunction2 is " << percent << "% faster than Myfunction1." << endl;
            break;
        default :
            cout << "MyFunction1 and Myfunction2 have the same speed." << endl;
    }
    return 0;
}
 

farzaneh0

New Member
دوست عزیز ممنون از لطفت ولی مشکل فعلی من این است که زمان اجرای یک برنامه را اندازه گیری کنم که متاسفانه همش صفر میده. اگه راهنماییم کنید بینهایت ممنون می شم
 
آخرین ویرایش توسط مدیر:

the_king

مدیرکل انجمن
دوست عزیز ممنون از لطفت ولی مشکل فعلی من این است که زمان اجرای یک برنامه را اندازه گیری کنم که متاسفانه همش صفر میده. اگه راهنماییم کنید بینهایت ممنون می شم

لطفا در متن پست هایتان کد های طولانی را نقل قول نکنید، بی جهت متن صفحه را طولانی می کند.

کد زیرزمان اجرای یک تابع را بر حسب ثانیه اندازه گیری می کند :
کد:
#include <iostream>
#include <math.h>

using namespace std;

const clock_t t = 5;

double round(double x)
{
    double n = floor(x);
    double m = ceil(x);
    return (fabs(x - n) < fabs(x - m)) ? n : m;
}

long MyFunction()
{
    long sum = 0;
    for (int i = 1; i <= 1000; i++)
        sum += i;
    return sum;
}

int main()
{
    clock_t end;
    long count = 0;
    cout << "Please wait...it take " << t << " seconds." << endl;
    end = clock() + CLOCKS_PER_SEC * t;
    while (clock() < end)
    {
        MyFunction();
        count++;
    }
    double elap = (double)t / (double)count;
    cout.precision(15);
    cout.setf(ios::fixed);
    cout << "Elapsed time for MyFunction = " << elap << " sec" << endl;
    return 0;
}
 

farzaneh0

New Member
دوست عزیز مطمئنی کدت درست است من که این کد را نوشتم برنامه در حالت اجرا موند و اصلا زمان اجرا را نشان نداد من الان تنها مشکلم این است که می خواهم زمان اجرای یک برنامه را اندازه گیری کنم ولی جواب زمان اجرا همیشه صفر است؟؟؟
 

the_king

مدیرکل انجمن
دوست عزیز مطمئنی کدت درست است من که این کد را نوشتم برنامه در حالت اجرا موند و اصلا زمان اجرا را نشان نداد من الان تنها مشکلم این است که می خواهم زمان اجرای یک برنامه را اندازه گیری کنم ولی جواب زمان اجرا همیشه صفر است؟؟؟

بله، مطمئن ام. این هم فایل اجرایی اش که ضمیمه پست شده.
 

پیوست ها

  • test.zip
    160.1 کیلوبایت · بازدیدها: 26

farzaneh0

New Member
دوست عزیز ممنون درست گفتی کد را دوباره با دقت اجرا کردم درست جواب داد در ضمن باور کن از صمیم قلب هم برای شما دعا کردم به خاطر کمک بزرگی که کردی فقط دوست عزیز یک سوال دیگه داشتم (البته ببخشید) و آن اینکه
برنامه من به ازای ورودی یکسان هر بار زمان اجرایش کمی متفاوت با دفعه قبل است به نظرت همین را به عنوان زمان اجرای برنامه در نظر بگیرم یا میانگین چند بار اجرای آن؟؟
در ضمن اگه درست فهمیده باشم کد شما می بینه که در مدت 5 ثانیه برنامه چند بار اجرا میشه سپس همین زمان 5 ثانیه را بر تعداد دفعات اجرا تقسیم می کنه درسته؟؟؟
 

the_king

مدیرکل انجمن
دوست عزیز ممنون درست گفتی کد را دوباره با دقت اجرا کردم درست جواب داد در ضمن باور کن از صمیم قلب هم برای شما دعا کردم به خاطر کمک بزرگی که کردی فقط دوست عزیز یک سوال دیگه داشتم (البته ببخشید) و آن اینکه
برنامه من به ازای ورودی یکسان هر بار زمان اجرایش کمی متفاوت با دفعه قبل است به نظرت همین را به عنوان زمان اجرای برنامه در نظر بگیرم یا میانگین چند بار اجرای آن؟؟
فرق چندانی نمی کنه، چون در هر صورت زمان اجرای برنامه ای که بدست می آید مستقل از وضعیتی که سیستم عامل
در همون لحظه اجرا داشته نیست و چون سیستم عامل در هر لحظه بار ترافیکی پردازشی و ورودی/خروجی متفاوتی داره،
در هیچ حالتی زمان بدست آمده مستقل نخواهد بود.

در ضمن اگه درست فهمیده باشم کد شما می بینه که در مدت 5 ثانیه برنامه چند بار اجرا میشه سپس همین زمان 5 ثانیه را بر تعداد دفعات اجرا تقسیم می کنه درسته؟؟؟
دقیقا همینطوره.
 

farzaneh0

New Member
یعنی هیچ کاری نمیشه کرد که زمان اجرای برنامه را بطور خالص در نظر گرفت (بدون دخالت پردازشهای دیگر) آخه وقتی من می خوام زمان اجرای چند برنامه را با هم مقایسه کنم و یکیش به ازای ورودی یکسان یکبار مثلا 0000242/0 است و بار دیگر 0000270/0 و دیگری هم به ازای ورودی یکسان یکبار 0000264/0 است و بار دیگر 0000280/. بالخره نمی توان گفت که زمان برنامه دومی از اولی کمتر است یا بیشتر!!!!
این مسئله به یک مشکل اساسی برای تز فوق لیسانس من تبدیل شده.
 

the_king

مدیرکل انجمن
یعنی هیچ کاری نمیشه کرد که زمان اجرای برنامه را بطور خالص در نظر گرفت (بدون دخالت پردازشهای دیگر) آخه وقتی من می خوام زمان اجرای چند برنامه را با هم مقایسه کنم و یکیش به ازای ورودی یکسان یکبار مثلا 0000242/0 است و بار دیگر 0000270/0 و دیگری هم به ازای ورودی یکسان یکبار 0000264/0 است و بار دیگر 0000280/. بالخره نمی توان گفت که زمان برنامه دومی از اولی کمتر است یا بیشتر!!!!
این مسئله به یک مشکل اساسی برای تز فوق لیسانس من تبدیل شده.

قرنطینه کردن cpu که نه، در سیستم عامل ویندوز نمیشه بطور کامل اینکار رو کرد.
در dos وضعیت بهتری هست، اما با مادربورد ها و cpu های قدیمی که رابطه دقیقی بین کد ماشین و زمان اجرا بود.
وقتی زمان اجرای یک کد برنامه ثابت نباشه، زمان اجرای خالص مفهومی نداره که بخواهید مشخص اش کنید.
زمان اجرای خالص فقط روی کاغذ بدست می یاد، کوچکترین تغییری در ولتاژ cpu یا اجرای همزمان چند پردازه و درخواست
i/o و صد ها تکنولوژی پیچیده داخل cpu مانع از تعیین کردن دقیق زمان اجرا میشه.

اگه قصد تون مقایسه دقیق کارایی دو کد برنامه است، با بررسی کد ماشین برنامه کامپایل شده و
بدست آوردن مجموع تعداد کلاک پالس ها با استفاده از جدول دستورات پردازنده، می توانید بطور دقیق
مشخص کنید که مثلا برای اندازه داده ورودی فلان، این کد فلان تعداد کلاک پالس صرف می کنه.
اما بدست آوردن زمان مورد نیاز برای اون تعداد کلاک پالس ها ثابت و دقیق نیست، چون در یک پردازنده مدرن
که چند هسته ای حقیقی یا مجازی است، و با مادربورد های مدرن که بطور متغیر ولتاژ cpu و فرکانس کاری اش
را کنترل می کنند، و با یک سیستم عامل چند پردازه ای مدرن، زمان اجرای کد بازه متغیری داره.
 

farzaneh0

New Member
یعنی تمام مقالاتی که زمان اجرای چند برنامه را اندازه گرفته و با هم روی نمودار مقایسه کرده اند از همین کدی که شما برای اندازه گیری زمان اجرا فرمودید استفاده کرده اند و برای یک ورودی مشخص که هر دفعه زمان اجراش با دفعه پیش متفاوت است یکی را به عنوان زمان اجرای آن در نظر گرفته اند؟؟؟
 

the_king

مدیرکل انجمن
یعنی تمام مقالاتی که زمان اجرای چند برنامه را اندازه گرفته و با هم روی نمودار مقایسه کرده اند از همین کدی که شما برای اندازه گیری زمان اجرا فرمودید استفاده کرده اند و برای یک ورودی مشخص که هر دفعه زمان اجراش با دفعه پیش متفاوت است یکی را به عنوان زمان اجرای آن در نظر گرفته اند؟؟؟

اندازه گیری زمان اجرا در یک سیستم نمونه فقط یکی از روش های مقایسه کردن سرعت اجرای کد ها است و
کد هایی که زمان اجرای شان را با هم مقایسه می کنند در حد چند میلی ثانیه نیستند و طبیعتا اختلاف بین شان
آنقدر محسوس هست که اختلاف های صدم ثانیه ای تاثیری در نتیجه گیری نداشته باشد.

مثلا مقایسه کردن سرعت مرتب سازی حبابی و درجی برای اندازه داده های ورودی 10000 و 100000

کد:
           Bubble Sort 10,000      Bubble Sort 100,000
         Random Numbers    Random Numbers
Time        0.366 sec.       36.702 sec.


           Insertion Sort 10,000      Insertion Sort 100,000
         Random Numbers    Random Numbers
Time        0.055 sec.       5.392 sec.

طبیعتا اگر اندازه داده های ورودی را در حد 10 می گرفتند، مقایسه ایندو کد با روش اندازه گیری زمان اجرا عملی نبود.
 

farzaneh0

New Member
خب آخر من برنامه ام جوری است که امکان اجرای آن برای داده های خیلی بزرگ نیست؟ به نظرتان چکار کنم؟؟؟
 

the_king

مدیرکل انجمن
خب آخر من برنامه ام جوری است که امکان اجرای آن برای داده های خیلی بزرگ نیست؟ به نظرتان چکار کنم؟؟؟

کدتان را داخل یک حلقه for با تعداد تکرار زیاد بندازید تا هر بار اجرایش چند ثانیه ای طول بکشد،
هر چه که تعداد تکرار ها بیشتر باشد، تفاوت های کوچک میان دو کد بیشتر مشخص می شود :

کد:
long x = 0;
for (x = 0; x < 500000; x++)
{

}
 

farzaneh0

New Member
خب فکر کنم باید مجموع زمان اجراها را هم بر تعداد تکرارها تقسیم کنم و در واقع میانگین بگیرم درسته؟؟؟
 

the_king

مدیرکل انجمن
خب فکر کنم باید مجموع زمان اجراها را هم بر تعداد تکرارها تقسیم کنم و در واقع میانگین بگیرم درسته؟؟؟

نه، منظورم میانگین نبود، اگر بخواهید میانگین بگیرید باید مدام بین هر بار اجرا زمان اجرا را اندازه گیری کنید
و جمع بزنید که چون خود کد زمان اجرای کمی دارد، این صرف کردن زمان اضافی اندک برای زمانگیری هم تاثیر نامطلوب
خواهد داشت.

منظورم این بود که در نتایج بجای درج کردن زمان سپری شده برای یکبار اجرا، زمان سپری شده برای مثلا 100000
بار اجرا رو ذکر کنید، در واقع واحد اندازه گیری را تغییر دهید، همانطور که فاصله بین شهر ها را بجای متر که
واحد اصلی است و دقیق تر هم هست به کیلومتر اعلام می کنند.
 

farzaneh0

New Member
خب دوست عزیز با کدی که شما برای اندازه گیری زمان اجرا به من گفتید اینطور بود که مثلا تعداد دفعات اجرای برنامه را در مدت 5 ثانیه اندازه گیری می کردیم و بعد 5 ثانیه را بر تعداد دفعات اجرا تقسیم می کردم حالا با این روش که بخواهم داخل حلقه for زمان اجرای برنامه را به ازای 10000 بار اجرا بدست آورم نمی شود مگر اینکه همان زمان حاصل از تقسیم 5 ثانیه بر تعداد دفعات اجرا را در 10000 ضرب کنم تا به جای زمان اجرای یک بار برنامه زمان اجرای 10000 بار برنامه بدست بیاد درسته؟؟؟
 

the_king

مدیرکل انجمن
خب دوست عزیز با کدی که شما برای اندازه گیری زمان اجرا به من گفتید اینطور بود که مثلا تعداد دفعات اجرای برنامه را در مدت 5 ثانیه اندازه گیری می کردیم و بعد 5 ثانیه را بر تعداد دفعات اجرا تقسیم می کردم حالا با این روش که بخواهم داخل حلقه for زمان اجرای برنامه را به ازای 10000 بار اجرا بدست آورم نمی شود مگر اینکه همان زمان حاصل از تقسیم 5 ثانیه بر تعداد دفعات اجرا را در 10000 ضرب کنم تا به جای زمان اجرای یک بار برنامه زمان اجرای 10000 بار برنامه بدست بیاد درسته؟؟؟

از نظر منطق ریاضی کاملا درسته، البته در عمل بدلیل ساختار اعداد اعشاری با ممیز شناور کمی خطا در محاسبه
خواهد داشت، اما تقریبا همون میشه.
 

جدیدترین ارسال ها

بالا