ข้อสังเกตด้านประสิทธิภาพ
คอมไพล์รูปแบบอย่างเหมาะสม
ข้อสังเกตด้านประสิทธิภาพ เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
การคอมไพล์มีต้นทุนสูง
การสร้าง std::regex จากสตริงจะคอมไพล์รูปแบบ ซึ่งมีต้นทุนสูง วิธีที่ช่วยได้มากที่สุดคือคอมไพล์เพียงครั้งเดียวแล้วนำกลับมาใช้ซ้ำ
- หลีกเลี่ยงการสร้าง regex ภายในลูป
- คอมไพล์ตอนเริ่มต้นหรือเมื่อใช้งานครั้งแรก
#include <iostream>
#include <regex>
int main() {
std::regex p("\\d+");
std::string inputs[] = {"12", "ab", "99"};
for (const auto& s : inputs) {
std::cout << s << ": " << std::regex_match(s, p) << '\n';
}
return 0;
}นำรูปแบบที่คอมไพล์แล้วกลับมาใช้ซ้ำ
สร้างรูปแบบหนึ่งครั้งนอกลูป แล้วนำกลับมาใช้กับข้อมูลเข้าทุกชุด การสร้างใหม่ในแต่ละรอบทำให้เสียเวลาโดยเปล่าประโยชน์
#include <iostream>
#include <regex>
#include <vector>
int main() {
static const std::regex p("[a-z]+");
std::vector<std::string> words = {"hello", "WORLD", "cpp"};
int matches = 0;
for (const auto& w : words) {
if (std::regex_match(w, p)) ++matches;
}
std::cout << "Matched: " << matches << '\n';
return 0;
}ค่าคงที่แบบคงอยู่
สำหรับรูปแบบที่ไม่เคยเปลี่ยน ให้ประกาศเป็นค่าคงที่แบบคงอยู่ภายในฟังก์ชัน เพื่อให้คอมไพล์เพียงครั้งเดียวตลอดการเรียกใช้ทั้งหมด
#include <iostream>
#include <regex>
bool isEmail(const std::string& s) {
static const std::regex p("\\w+@\\w+\\.\\w+");
return std::regex_match(s, p);
}
int main() {
std::cout << std::boolalpha;
std::cout << isEmail("a@b.com") << '\n';
std::cout << isEmail("nope") << '\n';
return 0;
}เลือกไวยากรณ์ที่เหมาะสม
รูปแบบไวยากรณ์ของ regex มีผลต่อความเร็วและความสามารถ std::regex::ECMAScript เป็นค่าเริ่มต้นและมีความสามารถมากที่สุด ส่วน std::regex::basic หรือ extended เรียบง่ายกว่าและบางครั้งทำงานได้เร็วกว่า
#include <iostream>
#include <regex>
int main() {
std::regex p("a+", std::regex::extended);
std::cout << std::boolalpha << std::regex_match("aaa", p) << '\n';
return 0;
}แฟล็กการเพิ่มประสิทธิภาพ
การเพิ่ม std::regex::optimize จะบอกให้กลไกใช้เวลาสร้างรูปแบบมากขึ้น เพื่อแลกกับการจับคู่ที่เร็วขึ้น ซึ่งคุ้มค่าเมื่อคุณจับคู่หลายครั้ง
#include <iostream>
#include <regex>
int main() {
std::regex p("\\d{3}-\\d{4}", std::regex::optimize);
std::cout << std::boolalpha << std::regex_match("123-4567", p) << '\n';
return 0;
}หลีกเลี่ยงการย้อนกลับแบบหายนะ
ตัวระบุจำนวนที่ซ้อนกัน เช่น (a+)+ อาจทำให้เวลาเพิ่มขึ้นแบบเอ็กซ์โพเนนเชียลกับข้อมูลเข้าบางแบบ ควรเลือกรูปแบบที่เรียบง่ายและไม่กำกวม
#include <iostream>
#include <regex>
int main() {
std::regex good("a+b");
std::cout << std::boolalpha << std::regex_match("aaaab", good) << '\n';
return 0;
}ใช้จุดยึดเมื่อทำได้
การใช้ ^ และ $ เป็นจุดยึดช่วยให้กลไกล้มเหลวได้อย่างรวดเร็ว แทนที่จะลองทุกตำแหน่งเริ่มต้น
#include <iostream>
#include <regex>
int main() {
std::regex p("^[a-z]{3}$");
std::cout << std::boolalpha;
std::cout << std::regex_search("abc", p) << '\n';
std::cout << std::regex_search("abcd", p) << '\n';
return 0;
}เลือกเครื่องมือที่เรียบง่ายกว่าเมื่อทำได้
หากคุณต้องการเพียงตรวจสอบสตริงย่อยแบบตายตัว std::string::find จะเร็วกว่า regex มาก ควรใช้ regex กับการจับคู่รูปแบบที่จำเป็นจริง ๆ
#include <iostream>
#include <string>
int main() {
std::string s = "hello world";
bool has = s.find("world") != std::string::npos;
std::cout << std::boolalpha << has << '\n';
return 0;
}การนำวัตถุการจับคู่กลับมาใช้ซ้ำ
เมื่อค้นหาซ้ำหลายครั้ง ให้ใช้ std::smatch เดิมซ้ำแทนการจัดสรรวัตถุใหม่ทุกครั้ง เพื่อลดค่าใช้จ่ายส่วนเกิน
#include <iostream>
#include <regex>
#include <vector>
int main() {
static const std::regex p("(\\d+)");
std::smatch m;
std::vector<std::string> data = {"x1", "y22", "z333"};
for (const auto& s : data) {
if (std::regex_search(s, m, p)) std::cout << m[1] << ' ';
}
std::cout << '\n';
return 0;
}จำกัดรูปแบบของคุณให้แคบลง
คลาสอักขระที่ระบุชัดเจนจะจับคู่ได้เร็วและปลอดภัยกว่าจุดที่ครอบคลุมทุกกรณี โปรดใช้ [0-9] แทน . เมื่อคุณหมายถึงตัวเลข
#include <iostream>
#include <regex>
int main() {
std::regex specific("[0-9]{2}");
std::cout << std::boolalpha;
std::cout << std::regex_match("42", specific) << '\n';
std::cout << std::regex_match("ab", specific) << '\n';
return 0;
}วัดผลก่อนปรับปรุงประสิทธิภาพ
นำสิ่งที่คุณเรียนรู้เกี่ยวกับ <chrono> มาประยุกต์ใช้: จับเวลาการใช้งานนิพจน์ปกติ เพื่อยืนยันว่าการเปลี่ยนแปลงช่วยได้จริงก่อนยอมรับการเปลี่ยนแปลงนั้น
#include <iostream>
#include <regex>
#include <chrono>
int main() {
using namespace std::chrono;
static const std::regex p("\\d+");
auto s = steady_clock::now();
int hits = 0;
for (int i = 0; i < 1000; ++i) {
if (std::regex_search(std::string("x") + std::to_string(i), p)) ++hits;
}
auto e = steady_clock::now();
std::cout << "hits=" << hits << ", timed: " << ((e - s).count() >= 0) << '\n';
return 0;
}ตรวจสอบอย่างรวดเร็ว
ทดสอบความเข้าใจของคุณเกี่ยวกับประสิทธิภาพของนิพจน์ปกติ
สรุปทบทวน
คุณได้เรียนรู้วิธีใช้นิพจน์ปกติอย่างมีประสิทธิภาพ:
- คอมไพล์รูปแบบเพียงครั้งเดียว โดยควรใช้
static constและนำกลับมาใช้ใหม่ - เลือกไวยากรณ์ที่เหมาะสม และพิจารณาใช้
optimize - หลีกเลี่ยงการย้อนกลับแบบทวีคูณที่รุนแรง และใช้จุดยึดเมื่อทำได้
- ใช้เครื่องมือที่เรียบง่ายกว่า เช่น
findสำหรับสตริงย่อยที่ตายตัว และวัดผลการเปลี่ยนแปลง
หลักสูตรนิพจน์ปกติจบลงเพียงเท่านี้
คำถามที่พบบ่อย
บทเรียน “ข้อสังเกตด้านประสิทธิภาพ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ข้อสังเกตด้านประสิทธิภาพ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ข้อสังเกตด้านประสิทธิภาพ”
คอมไพล์รูปแบบอย่างเหมาะสม คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “ข้อสังเกตด้านประสิทธิภาพ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐาน regex
- กลุ่มจับคู่
- การค้นหาและแทนที่
- ข้อสังเกตด้านประสิทธิภาพ