الخوارزميات و هياكل البيانات طريقة عرض المدة التي يستغرقها تنفيذ الكود

الطريقة الصحيحة لقياس المدة التي يستغرقها تنفيذ الكود

في البداية, مهما كانت لغة البرمجة التي تستخدمها يجب أن تفكر كالتالي عندما تقوم بقياس المدة التي يستغرقها تنفيذ الكود:

قم بتجربة الكود على كمية ضخمة من البيانات, فمثلاً إذا أردت معرفة كم سيستغرق تنفيذ حلقة تكرر الموضوع فيها من 1 إلى n فيجب أن تدخل قيمة كبيرة للمتغير n وقت التشغيل مثل 10000 - 50000 - 100000 أو قيم أكبر.
لا تقم بالتجربة على قيم صغيرة مثل 50 و 100 لأن المهمات الصغيرة قد ينجزها حاسوبك بلمح البصر و بالتالي فإن وقت تنفيذها قد يظهر لك 0 و بالتالي فإن هذا لن يفيدك إطلاقاً. تذكر دائماً أنه كلما كان عدد التكرار أكبر كلما ظهر لك الفرق الذي تحتاج معرفته أكثر, بالإضافة إلى أنك يجب دائماً أن تتوقع العمل بأعداد كبيرة في المشاريع التي تفعلها.

عند حساب الوقت الذي يستغرقه الكود حتى يتنفذ لا تتوقع أن تحصل على وقت ثابت في كل مرة تقوم فيها بتشغيل البرنامج و السبب في ذلك أن حاسوبك الذي تجرب عليه البرنامج يقوم بتشغيل العديد من البرامج و الخدمات في وقت واحد في الخلفية و كل واحد منهم ينفذ أوامر كثيرة تماماً كالأوامر التي تحاول تجربة تنفيذها.
لهذا السبب ننصحك دائماً بتجربة الكود عدة مرات, و لنفترض مثلاً 5 أو 10 مرات, و في كل مرة تقوم فيها بتشغيل الكود قم بحفظ الوقت الذي استغرقه للتدوين في ملف نصي أو دونه على ورقة أو إحفظه بشكل مؤقت بأي طريقة ترتاح بها.

بهذه الطريقة إذا توصلت لأكثر من طريقة لكتابة نفس الكود, تستطيع تجربة تشغيل كل طريقة منهم و تدوين الوقت الذي تحتاجه كل طريقة منهم. من خلال مقارنة الوقت الذي تحتاجه كل طريقة منهم ستعرف أي كود هو الأفضل بينهم.


معلومة

في البرامج الكبيرة و المواقع نقوم في العادة بوضع كل مهمة خاصة في المشروع بداخل دالة.
هكذا يصبح تطوير المشروع أمر سهل لأن الكود مرتب للغاية و أي مهمة نحتاج تعديلها نتوجه للدالة التي وضعنا كيف تتنفذ بداخلها.

من أهم الأشياء التي تحصل عليها حين ترتب الكود بشكل صحيح هي إمكانية معرفة المدة التي يستغرقها تنفيذ أي مهمة بكل السهولة.
بكل بساطة تستطيع تسجيل الوقت الذي بدأت فيه الدالة بالتنفيذ و تسجيل الوقت الذي إنتهت به. بعدها تقوم بطرح وقت الإنتهاء من وقت البداية لتحصل على المدة تنفيذ الكود من البداية إلى النهاية.

طريقة عرض الوقت الذي استغرقه تنفيذ الكود بلغة بايثون

لعرض الوقت الذي استغرقه تنفيذ الكود بلغة بايثون, يمكنك تضمن الموديول time و استخدام الدالة time() كالتالي.

import time

start_time = time.time()

# هنا نضع الأوامر التي نريد حساب الوقت الذي تحتاجه حتى تتنفذ

end_time = time.time()

print("Execution Time in Seconds:", end_time - start_time)
	


في المثال التالي قمنا بحساب الوقت الذي يستغرقه الحاسوب لطباعة ناتج جمع جميع الأرقام الموجودة من 1 إلى n.
يمكنك كتابة الكود التالي بطرق أخرى طبعاً و لكننا تعمدنا كتابته بهذا الشكل حتى يكون سهل الفهم.


مثال

# time هنا قمنا بتضمين الموديول
import time

# لاحظ أننا افترضنا أن المستخدم قد يدخل عدد كبير مثل مليون
n = 1000000

# n سنستخدمه لتخزين ناتج جمع جميع الأرقام الموجودة من 1 إلى s المتغير
s = 0

# start_time هنا قمنا بتخزين الوقت الحالي للجهاز في المتغير
# لاحظ أننا قمنا بتخزين الوقت مباشرةً قبل تعريف الحلقة لأننا نريد تخزين الوقت الحالي قبل بداية تنفيذ الحلقة
start_time = time.time()

# s الحالية على قيمة المتغير i في كل دورة سيتم إضافة قيمة العداد
# طبعاً هذه العملية ستكرر مليون مرة خلال أجزاء من الثانية
for i in range(1, n + 1):
    s += i

# end_time هنا قمنا بإعادة تخزين الوقت الحالي للجهاز في المتغير
# لاحظ أننا قمنا بتخزين الوقت مباشرةً بعد إنتهاء الحلقة لأننا نريد تخزين الوقت الحالي بعد أن تنفذت الحلقة
end_time = time.time()

# النهائية s هنا قمنا بطباعة قيمة المتغير
print("s =", s)

# هنا قمنا بطباعة الوقت الذي استغرقه تنفيذ الحلقة و الذي يساوي وقت إنتهاء التنفيذ ناقص وقت بداية التنفيذ
print("Execution Time in Seconds:", end_time - start_time)
		

سنحصل على نتيجة تشبه النتيجة التالية عند التشغيل حيث أن قيمة s ستكون هي نفسها دائماً.
أما وقت التنفيذ فسيتغير حتماً بمقدار بسيط جداً في كل مرة يتم فيها تشغيل البرنامج.

s = 250000500000
Execution Time in Seconds: 0.08177542686462402
		

طريقة عرض الوقت الذي استغرقه تنفيذ الكود بلغة جافا

إلعرض الوقت الذي استغرقه تنفيذ الكود بلغة جافا, يمكنك استخدام الدالة nanoTime() كالتالي.
ملاحظة: قسمنا الجواب النهائي على مليار للتحويل من nano seconds إلى seconds, أي حتى نعرض الوقت المستغرق بالثواني.

double startTime = System.nanoTime();

// هنا نضع الأوامر التي نريد حساب الوقت الذي تحتاجه حتى تتنفذ

double endTime = System.nanoTime();

System.out.println("Execution Time in Seconds: " + ((endTime - startTime) / 1000000000));
	


في المثال التالي قمنا بحساب الوقت الذي يستغرقه الحاسوب لطباعة ناتج جمع جميع الأرقام الموجودة من 1 إلى n.
يمكنك كتابة الكود التالي بطرق أخرى طبعاً و لكننا تعمدنا كتابته بهذا الشكل حتى يكون سهل الفهم.


مثال

public class Main {
    
    public static void main(String args[])
    {		
		// لاحظ أننا افترضنا أن المستخدم قد يدخل عدد كبير مثل مليون
        int n = 1000000;
		
		// n سنستخدمه لتخزين ناتج جمع جميع الأرقام الموجودة من 1 إلى s المتغير
        long s = 0;
        
		// startTime هنا قمنا بتخزين الوقت الحالي للجهاز في المتغير
		// لاحظ أننا قمنا بتخزين الوقت مباشرةً قبل تعريف الحلقة لأننا نريد تخزين الوقت الحالي قبل بداية تنفيذ الحلقة
        double startTime = System.nanoTime();
        
		// s الحالية على قيمة المتغير i في كل دورة سيتم إضافة قيمة العداد
		// طبعاً هذه العملية ستكرر مليون مرة خلال أجزاء من الثانية
        for (int i = 1; i <= n; i++)
        {
            s += i;
        }
        
		// endTime هنا قمنا بإعادة تخزين الوقت الحالي للجهاز في المتغير
		// لاحظ أننا قمنا بتخزين الوقت مباشرةً بعد إنتهاء الحلقة لأننا نريد تخزين الوقت الحالي بعد أن تنفذت الحلقة
        double endTime = System.nanoTime();

        // النهائية s هنا قمنا بطباعة قيمة المتغير
        System.out.println("s = " + s);
        
        // هنا قمنا بطباعة الوقت الذي استغرقه تنفيذ الحلقة و الذي يساوي وقت إنتهاء التنفيذ ناقص وقت بداية التنفيذ
        System.out.println("Execution Time in Seconds: " + ((endTime - startTime) / 1000000000));
    }

}
		

سنحصل على نتيجة تشبه النتيجة التالية عند التشغيل حيث أن قيمة s ستكون هي نفسها دائماً.
أما وقت التنفيذ فسيتغير حتماً بمقدار بسيط جداً في كل مرة يتم فيها تشغيل البرنامج.

s = 250000500000
Execution Time in Seconds: 0.0025516
		

طريقة عرض الوقت الذي استغرقه تنفيذ الكود بلغة C

لعرض الوقت الذي استغرقه تنفيذ الكود بلغة C, يمكنك تضمين المكتبة time التي تحتوي على الدالة Clock() التي ترجع الوقت الحالي و النوع clock_t الذي سنستخدمه لتخزين الوقت الحالي الذي ترجعه الدالة.
ملاحظة: قسمنا الجواب النهائي على الثابت CLOCKS_PER_SEC حتى نعرض الوقت المستغرق بالثواني.

#include <time.h> 

clock_t startTime;
clock_t endTime;

startTime = clock(); 
    
// هنا نضع الأوامر التي نريد حساب الوقت الذي تحتاجه حتى تتنفذ
    
endTime = clock();

printf("Execution Time in Seconds: %f", ((double)endTime - startTime) / CLOCKS_PER_SEC); 
	


في المثال التالي قمنا بحساب الوقت الذي يستغرقه الحاسوب لطباعة ناتج جمع جميع الأرقام الموجودة من 1 إلى n.
يمكنك كتابة الكود التالي بطرق أخرى طبعاً و لكننا تعمدنا كتابته بهذا الشكل حتى يكون سهل الفهم.


مثال

#include <stdio.h>
#include <time.h> 

void main()
{
	// لتخزين وقت التوقف endTime لتخزين وقت البدء و المتغير startTime سنستخدم المتغير
    clock_t startTime;
    clock_t endTime;
    
	// لاحظ أننا افترضنا أن المستخدم قد يدخل عدد كبير مثل مليون
    int n = 1000000;
	
	// n سنستخدمه لتخزين ناتج جمع جميع الأرقام الموجودة من 1 إلى s المتغير
    double s = 0;
	
	// startTime هنا قمنا بتخزين الوقت الحالي للجهاز في المتغير
    // لاحظ أننا قمنا بتخزين الوقت مباشرةً قبل تعريف الحلقة لأننا نريد تخزين الوقت الحالي قبل بداية تنفيذ الحلقة
    startTime = clock(); 
    
	// s الحالية على قيمة المتغير i في كل دورة سيتم إضافة قيمة العداد
    // طبعاً هذه العملية ستكرر مليون مرة خلال أجزاء من الثانية
    for (int i = 1; i <= n; i++)
    {
        s += i;
    }
    
	// endTime هنا قمنا بإعادة تخزين الوقت الحالي للجهاز في المتغير
    // لاحظ أننا قمنا بتخزين الوقت مباشرةً بعد إنتهاء الحلقة لأننا نريد تخزين الوقت الحالي بعد أن تنفذت الحلقة
    endTime = clock();
    
	// النهائية s هنا قمنا بطباعة قيمة المتغير
    printf("s = %lf", s);
    
	// هنا قمنا بطباعة الوقت الذي استغرقه تنفيذ الحلقة و الذي يساوي وقت إنتهاء التنفيذ ناقص وقت بداية التنفيذ
    printf("\nExecution Time in Seconds: %f", ((double)endTime - startTime) / CLOCKS_PER_SEC); 

}
		

سنحصل على نتيجة تشبه النتيجة التالية عند التشغيل حيث أن قيمة s ستكون هي نفسها دائماً.
أما وقت التنفيذ فسيتغير حتماً بمقدار بسيط جداً في كل مرة يتم فيها تشغيل البرنامج.

s = 500000500000.000000
Execution Time in Seconds: 0.003000
		

طريقة عرض الوقت الذي استغرقه تنفيذ الكود بلغة C#

لعرض الوقت الذي استغرقه تنفيذ الكود بلغة C#, يمكنك استخدام دوال الكلاس Stopwatch كالتالي.
ملاحظة: قسمنا الجواب النهائي على 1000 للتحويل من milliseconds إلى seconds, أي حتى نعرض الوقت المستغرق بالثواني.

var stopwatch = new System.Diagnostics.Stopwatch();

stopwatch.Start();

// هنا نضع الأوامر التي نريد حساب الوقت الذي تحتاجه حتى تتنفذ

stopwatch.Stop();

Console.WriteLine("Execution Time in Seconds: " + (double)stopwatch.ElapsedMilliseconds / 1000);
	


في المثال التالي قمنا بحساب الوقت الذي يستغرقه الحاسوب لطباعة ناتج جمع جميع الأرقام الموجودة من 1 إلى n.
يمكنك كتابة الكود التالي بطرق أخرى طبعاً و لكننا تعمدنا كتابته بهذا الشكل حتى يكون سهل الفهم.


مثال

using System;

class Program
{
    static void Main(string[] args)
    {
		// و الذي يمثل ساعة توقيف Stopwatch هنا قمنا بإنشاء كائن من الكلاس 
        var stopwatch = new System.Diagnostics.Stopwatch();

        // لاحظ أننا افترضنا أن المستخدم قد يدخل عدد كبير مثل مليون
        int n = 1000000;

        // n سنستخدمه لتخزين ناتج جميع الأرقام الموجودة من 1 إلى s المتغير
        long s = 0;

        // لتخزين الوقت الحالي قبل تعريف الحلقة لأننا نريد تخزين الوقت الحالي قبل بداية تنفيذ الحلقة Start() هنا قمنا باستدعاء الدالة
        stopwatch.Start();

        // s الحالية على قيمة المتغير i في كل دورة سيتم إضافة قيمة العداد
        // طبعاً هذه العملية ستكرر مليون مرة خلال أجزاء من الثانية
        for (int i = 1; i <= n; i++)
        {
            s += i;
        }

        // لتخزين الوقت الحالي بعد أن تنفذت الحلقة حيث أننا نريد حساب وقت تنفيذ الحلقة فقط Stop() هنا قمنا باستدعاء الدالة
        stopwatch.Stop();

        // النهائية s هنا قمنا بطباعة قيمة المتغير
        Console.WriteLine("s = " + s);

        // هنا قمنا بطباعة الوقت الذي استغرقه تنفيذ الحلقة و الذي يساوي وقت إنتهاء التنفيذ ناقص وقت بداية التنفيذ
        Console.WriteLine("Execution Time in Seconds: " + ((double)stopwatch.ElapsedMilliseconds / 1000));

        Console.ReadKey();
    }
    
}
		

سنحصل على نتيجة تشبه النتيجة التالية عند التشغيل حيث أن قيمة s ستكون هي نفسها دائماً.
أما وقت التنفيذ فسيتغير حتماً بمقدار بسيط جداً في كل مرة يتم فيها تشغيل البرنامج.

s = 500000500000
Execution Time in Seconds: 0.002
		

طريقة عرض الوقت الذي استغرقه تنفيذ الكود بلغة C++

لعرض الوقت الذي استغرقه تنفيذ الكود بلغة C++, يمكنك تضمين المكتبة time التي تحتوي على الدالة Clock() التي ترجع الوقت الحالي و النوع clock_t الذي سنستخدمه لتخزين الوقت الحالي الذي ترجعه الدالة.
ملاحظة: قسمنا الجواب النهائي على الثابت CLOCKS_PER_SEC حتى نعرض الوقت المستغرق بالثواني.

#include <time.h> 

clock_t startTime;
clock_t endTime;

startTime = clock(); 
    
// هنا نضع الأوامر التي نريد حساب الوقت الذي تحتاجه حتى تتنفذ
    
endTime = clock();

std::cout << "Execution Time in Seconds: " << ((double)endTime - startTime) / CLOCKS_PER_SEC; 
	


في المثال التالي قمنا بحساب الوقت الذي يستغرقه الحاسوب لطباعة ناتج جمع جميع الأرقام الموجودة من 1 إلى n.
يمكنك كتابة الكود التالي بطرق أخرى طبعاً و لكننا تعمدنا كتابته بهذا الشكل حتى يكون سهل الفهم.


مثال

#include <iostream>
#include <time.h>

using namespace std;

int main()
{
    // لتخزين وقت التوقف endTime لتخزين وقت البدء و المتغير startTime سنستخدم المتغير
    clock_t startTime;
    clock_t endTime;

    // لاحظ أننا افترضنا أن المستخدم قد يدخل عدد كبير مثل مليون
    int n = 1000000;

    // n سنستخدمه لتخزين ناتج جمع جميع الأرقام الموجودة من 1 إلى s المتغير
    double s = 0;

    // startTime هنا قمنا بتخزين الوقت الحالي للجهاز في المتغير
    // لاحظ أننا قمنا بتخزين الوقت مباشرةً قبل تعريف الحلقة لأننا نريد تخزين الوقت الحالي قبل بداية تنفيذ الحلقة
    startTime = clock();

    // s الحالية على قيمة المتغير i في كل دورة سيتم إضافة قيمة العداد
    // طبعاً هذه العملية ستكرر مليون مرة خلال أجزاء من الثانية
    for (int i = 1; i <= n; i++)
    {
        s += i;
    }

    // endTime هنا قمنا بإعادة تخزين الوقت الحالي للجهاز في المتغير
    // لاحظ أننا قمنا بتخزين الوقت مباشرةً بعد إنتهاء الحلقة لأننا نريد تخزين الوقت الحالي بعد أن تنفذت الحلقة
    endTime = clock();

    // النهائية s هنا قمنا بطباعة قيمة المتغير
    cout << "s = " << s << endl;

    // هنا قمنا بطباعة الوقت الذي استغرقه تنفيذ الحلقة و الذي يساوي وقت إنتهاء التنفيذ ناقص وقت بداية التنفيذ
    cout << "Execution Time in Seconds: " << ((double)endTime - startTime) / CLOCKS_PER_SEC << endl;

    return 0;
}
		

سنحصل على نتيجة تشبه النتيجة التالية عند التشغيل حيث أن قيمة s ستكون هي نفسها دائماً.
أما وقت التنفيذ فسيتغير حتماً بمقدار بسيط جداً في كل مرة يتم فيها تشغيل البرنامج.

s = 5e+011
Execution Time in Seconds: 0.003
		

الدورات

أدوات مساعدة

الأقسام

دورات
مقالات أسئلة مشاريع كتب