การวัดประสิทธิภาพโค้ด
ทดสอบประสิทธิภาพด้วย chrono
การวัดประสิทธิภาพโค้ด เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 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
คำถามที่พบบ่อย
บทเรียน “การวัดประสิทธิภาพโค้ด” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การวัดประสิทธิภาพโค้ด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การวัดประสิทธิภาพโค้ด”
ทดสอบประสิทธิภาพด้วย chrono คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การวัดประสิทธิภาพโค้ด” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ช่วงเวลาและนาฬิกา
- จุดเวลา
- การวัดประสิทธิภาพโค้ด
- ปฏิทินและเขตเวลา