قياس أداء التعليمات البرمجية
أجرِ اختبار أداء باستخدام chrono
قياس أداء التعليمات البرمجية درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.
لماذا نقيس الأداء؟
يساعدك قياس مدة تشغيل الشيفرة على العثور على الاختناقات والتحقق من التحسينات. وباستخدام <chrono> تحصل على قياس وقت محمول وآمن من ناحية الأنواع.
- قِس الأداء قبل إجراء التحسينات.
- استخدم ساعة ثابتة للحصول على فواصل زمنية موثوقة.
#include <iostream>
#include <chrono>
int main() {
using namespace std::chrono;
auto start = steady_clock::now();
auto end = steady_clock::now();
std::cout << "Timed a block: " << ((end - start).count() >= 0) << '\n';
return 0;
}النمط الأساسي
يظل نمط قياس الأداء نفسه دائمًا: التقط قيمة now() قبل تنفيذ العمل، ونفّذه، ثم التقط قيمة now() بعده، واطرح القيمتين.
#include <iostream>
#include <chrono>
int main() {
using namespace std::chrono;
auto start = steady_clock::now();
long sum = 0;
for (int i = 0; i < 100000; ++i) sum += i;
auto end = steady_clock::now();
std::cout << "Sum: " << sum << ", elapsed >= 0: " << ((end - start).count() >= 0) << '\n';
return 0;
}اختيار الوحدة
اختر الوحدة التي تناسب حجم العمل. استخدم microseconds أو nanoseconds للحلقات السريعة، وmilliseconds للمهام الأكبر.
#include <iostream>
#include <chrono>
int main() {
using namespace std::chrono;
auto start = steady_clock::now();
long sum = 0;
for (int i = 0; i < 500000; ++i) sum += i;
auto end = steady_clock::now();
auto us = duration_cast<microseconds>(end - start);
std::cout << "Result: " << sum << ", us non-negative: " << (us.count() >= 0) << '\n';
return 0;
}قياس الوقت بالفاصلة العائمة
للحصول على ثوانٍ مقروءة للإنسان مع أجزاء كسرية، استخدم duration<double> للحفاظ على الدقة الأقل من ثانية.
#include <iostream>
#include <chrono>
int main() {
using namespace std::chrono;
auto start = steady_clock::now();
long sum = 0;
for (int i = 0; i < 200000; ++i) sum += i % 7;
auto end = steady_clock::now();
duration<double> secs = end - start;
std::cout << "Computed " << sum << ", seconds >= 0: " << (secs.count() >= 0) << '\n';
return 0;
}مؤقت قابل لإعادة الاستخدام
غلّف هذا النمط داخل دالة مساعدة صغيرة، لتتمكن من قياس زمن أي كائن قابل للاستدعاء بسهولة وتجنّب تكرار الشيفرة.
#include <iostream>
#include <chrono>
long long timeWork() {
using namespace std::chrono;
auto s = steady_clock::now();
long acc = 0;
for (int i = 0; i < 100000; ++i) acc += i;
auto e = steady_clock::now();
return duration_cast<microseconds>(e - s).count();
}
int main() {
std::cout << "Microseconds non-negative: " << (timeWork() >= 0) << '\n';
return 0;
}تجنّب إزالة الشيفرة الميتة
قد يحذف المصرّف العمل الذي لا تُستخدم نتيجته، مما يفسد قياسات الأداء. احرص دائمًا على استخدام النتيجة، مثل طباعتها أو جمعها في متغير ظاهر.
#include <iostream>
#include <chrono>
int main() {
using namespace std::chrono;
auto s = steady_clock::now();
volatile long sink = 0;
for (int i = 0; i < 100000; ++i) sink += i;
auto e = steady_clock::now();
std::cout << "Sink used: " << (sink > 0) << ", elapsed >= 0: " << ((e - s).count() >= 0) << '\n';
return 0;
}تشغيلات الإحماء
قد يكون التشغيل الأول أبطأ بسبب ذاكرات التخزين المؤقت والتهيئة الكسولة. نفّذ مرور إحماء قبل القياس للحصول على أرقام أكثر استقرارًا.
#include <iostream>
#include <chrono>
long work() {
long a = 0;
for (int i = 0; i < 50000; ++i) a += i;
return a;
}
int main() {
using namespace std::chrono;
work();
auto s = steady_clock::now();
long r = work();
auto e = steady_clock::now();
std::cout << r << " measured, ok: " << ((e - s).count() >= 0) << '\n';
return 0;
}حساب متوسط عدة تشغيلات
يكون القياس الواحد متأثرًا بالضوضاء. نفّذ العمل مرات عديدة، واجمع المدد المنقضية، ثم اقسمها للحصول على متوسط مستقر.
#include <iostream>
#include <chrono>
int main() {
using namespace std::chrono;
long long total = 0;
const int runs = 5;
for (int r = 0; r < runs; ++r) {
auto s = steady_clock::now();
long acc = 0;
for (int i = 0; i < 100000; ++i) acc += i;
auto e = steady_clock::now();
total += duration_cast<microseconds>(e - s).count();
}
std::cout << "Average us non-negative: " << ((total / runs) >= 0) << '\n';
return 0;
}مقارنة نهجين
يبرُز قياس الأداء عند مقارنة التطبيقات. قِس زمن كل تطبيق بالطريقة نفسها، ثم قارن المدد الزمنية الناتجة.
#include <iostream>
#include <chrono>
#include <vector>
int main() {
using namespace std::chrono;
std::vector<int> v;
auto s1 = steady_clock::now();
for (int i = 0; i < 10000; ++i) v.push_back(i);
auto e1 = steady_clock::now();
v.clear();
v.reserve(10000);
auto s2 = steady_clock::now();
for (int i = 0; i < 10000; ++i) v.push_back(i);
auto e2 = steady_clock::now();
std::cout << "Both timed: " << (((e1 - s1).count() >= 0) && ((e2 - s2).count() >= 0)) << '\n';
return 0;
}احذر من دقة القياس
إذا كان العمل المقاس أقصر من نبضة الساعة، فقد تقرأ القيمة صفرًا. كرّر العمل عددًا كافيًا من المرات لتتجاوز دقة الساعة.
#include <iostream>
#include <chrono>
int main() {
using namespace std::chrono;
auto s = steady_clock::now();
int x = 1 + 1;
auto e = steady_clock::now();
auto ns = duration_cast<nanoseconds>(e - s).count();
std::cout << "x=" << x << ", tiny work may read low: " << (ns >= 0) << '\n';
return 0;
}عرض النتائج
حوّل المدة النهائية إلى وحدة سهلة القراءة واطبعها. أبقِ النتيجة المستخدمة ظاهرة حتى لا يتمكن المُحسِّن من إزالة العمل.
#include <iostream>
#include <chrono>
int main() {
using namespace std::chrono;
auto s = steady_clock::now();
long acc = 0;
for (int i = 0; i < 300000; ++i) acc += (i * 3) % 11;
auto e = steady_clock::now();
auto ms = duration_cast<milliseconds>(e - s).count();
std::cout << "acc=" << acc << ", ms >= 0: " << (ms >= 0) << '\n';
return 0;
}تحقق سريع
اختبر مدى فهمك لمزالق قياس الأداء.
مراجعة
تعلّمت كيفية قياس أداء التعليمات البرمجية باستخدام <chrono>:
- التقاط قيمة
steady_clock::now()قبل التنفيذ وبعده، ثم طرح القيمتين - اختيار وحدة مناسبة باستخدام
duration_cast - إجراء إحماء، وحساب متوسط عدة تشغيلات، واستخدام النتائج لمنع حذف التعليمات البرمجية غير المستخدمة
- الانتباه إلى دقة الساعة عند قياس أحمال عمل صغيرة جدًا
بعد ذلك، ستستكشف أنواع التقويم والمناطق الزمنية في C++20.
الأسئلة الشائعة
هل درس «قياس أداء التعليمات البرمجية» مجاني؟
نعم — نص درس «قياس أداء التعليمات البرمجية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.
ماذا ستتعلم في «قياس أداء التعليمات البرمجية»؟
أجرِ اختبار أداء باستخدام chrono تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟
لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «قياس أداء التعليمات البرمجية»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟
نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- المدد والساعات
- النقاط الزمنية
- قياس أداء التعليمات البرمجية
- التقويم والمناطق الزمنية