เคล็ดลับด้านประสิทธิภาพ
ใช้ regexp ที่คอมไพล์แล้วซ้ำ
เคล็ดลับด้านประสิทธิภาพ เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
การคอมไพล์มีต้นทุน
การเปลี่ยนสตริงรูปแบบให้เป็น regexp ที่ใช้งานได้ต้องใช้การประมวลผล การทำเช่นนี้ทุกครั้งที่เรียกใช้จะเสียเวลาโดยเปล่าประโยชน์ โดยเฉพาะในลูปหรือเส้นทางการทำงานที่ถูกเรียกบ่อย
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile("[0-9]+")
fmt.Println(re.MatchString("x9"))
}คอมไพล์ครั้งเดียว ใช้ซ้ำบ่อย ๆ
กฎสำคัญคือ คอมไพล์รูปแบบ ครั้งเดียว แล้วใช้ *regexp.Regexp ซ้ำ ตัวแปรระดับแพ็กเกจเป็นตำแหน่งที่มักใช้เก็บค่านี้
package main
import (
"fmt"
"regexp"
)
var numRe = regexp.MustCompile("[0-9]+")
func hasNumber(s string) bool {
return numRe.MatchString(s)
}
func main() {
fmt.Println(hasNumber("a1"))
fmt.Println(hasNumber("abc"))
}หลีกเลี่ยงการคอมไพล์ในลูป
อย่าเรียกใช้ MustCompile ภายในลูป ควรคอมไพล์ก่อนเริ่มลูป แล้วใช้ค่าเดิมในการทำซ้ำแต่ละครั้ง
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile("[a-z]+")
inputs := []string{"go", "123", "rust"}
for _, s := range inputs {
fmt.Println(s, re.MatchString(s))
}
}Regexp ปลอดภัยต่อการใช้ร่วมกัน
*regexp.Regexp ที่คอมไพล์แล้ว ปลอดภัยสำหรับการใช้งานพร้อมกัน โดย goroutine หลายตัว คุณสามารถใช้ตัวแปรส่วนกลางเพียงตัวเดียวกับทุกตัวได้
package main
import (
"fmt"
"regexp"
)
var re = regexp.MustCompile("go")
func main() {
fmt.Println(re.MatchString("golang"))
}บางครั้ง strings เร็วกว่า
สำหรับสตริงย่อยแบบตรงตัว strings.Contains ทำงานได้เร็วกว่า regexp ควรใช้ regexp เฉพาะเมื่อจำเป็นต้องใช้ความสามารถของรูปแบบจริง ๆ
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Contains("hello world", "world"))
}เลือกใช้รูปแบบที่ยึดจุดเริ่มต้น
การยึดจุดเริ่มต้นด้วย ^ ทำให้กลไกหยุดทำงานได้อย่างรวดเร็วเมื่อจุดเริ่มต้นไม่ตรงกัน แทนที่จะสแกนสตริงทั้งหมด
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile("^https?://")
fmt.Println(re.MatchString("http://site"))
fmt.Println(re.MatchString("see http://x"))
}จำกัดจำนวนการจับคู่
เมื่อคุณต้องการเพียงไม่กี่ส่วนที่จับคู่ได้ ให้ส่งค่า n ขนาดเล็กให้เมธอดค้นหาทั้งหมด แทนการส่งค่า -1 เพื่อให้หยุดได้เร็วขึ้น
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile("[0-9]+")
fmt.Println(re.FindAllString("1 2 3 4 5", 2))
}ระวังรูปแบบที่ย้อนกลับไปจับคู่
กลไก RE2 ของ Go หลีกเลี่ยงการย้อนกลับไปจับคู่แบบรุนแรงได้ แต่รูปแบบที่กว้างเกินไป เช่น .* ก็ยังอาจสแกนข้อมูลมากเกินจำเป็นได้ ควรระบุรูปแบบให้เจาะจง
package main
import (
"fmt"
"regexp"
)
func main() {
broad := regexp.MustCompile(".*=.*")
precise := regexp.MustCompile("[a-z]+=[0-9]+")
fmt.Println(broad.MatchString("x=1"), precise.MatchString("x=1"))
}ทำให้อักขระพิเศษในข้อมูลนำเข้าปลอดภัย
หากรูปแบบมีข้อความจากผู้ใช้ ให้ทำให้ข้อความนั้นปลอดภัยด้วย regexp.QuoteMeta เพื่อให้อักขระพิเศษถูกตีความเป็นอักขระตรงตัว
package main
import (
"fmt"
"regexp"
)
func main() {
user := "a.b"
re := regexp.MustCompile(regexp.QuoteMeta(user))
fmt.Println(re.MatchString("a.b"))
fmt.Println(re.MatchString("axb"))
}จัดเก็บรูปแบบที่คอมไพล์แล้วใน cache
หากสร้างรูปแบบขณะโปรแกรมทำงาน ให้จัดเก็บรูปแบบที่คอมไพล์แล้วในแผนที่ โดยใช้สตริงรูปแบบเป็นคีย์ เพื่อหลีกเลี่ยงการคอมไพล์รูปแบบเดิมซ้ำ
package main
import (
"fmt"
"regexp"
)
var cache = map[string]*regexp.Regexp{}
func get(p string) *regexp.Regexp {
if re, ok := cache[p]; ok {
return re
}
re := regexp.MustCompile(p)
cache[p] = re
return re
}
func main() {
fmt.Println(get("[0-9]+").MatchString("7"))
}ประกอบทุกอย่างเข้าด้วยกัน
ตัวตรวจสอบที่ปรับแต่งมาอย่างดีจะคอมไพล์เพียงครั้งเดียว ยึดจุดเริ่มต้นของรูปแบบ และใช้ร่วมกันกับการเรียกใช้ทั้งหมด
package main
import (
"fmt"
"regexp"
)
var emailRe = regexp.MustCompile("^[a-z0-9]+@[a-z]+\\.[a-z]+$")
func main() {
fmt.Println(emailRe.MatchString("me@site.com"))
}ตรวจสอบอย่างรวดเร็ว
เคล็ดลับด้านประสิทธิภาพของ regexp ที่สำคัญที่สุดเพียงข้อเดียวคืออะไร
ทบทวน: เคล็ดลับด้านประสิทธิภาพ
คุณได้เรียนรู้การใช้ regexp อย่างมีประสิทธิภาพดังนี้:
- คอมไพล์เพียงครั้งเดียวด้วย
MustCompileแล้วใช้ซ้ำ ซึ่งปลอดภัยสำหรับการทำงานพร้อมกัน - เลือกใช้
stringsสำหรับสตริงย่อยแบบตรงตัว ยึดจุดเริ่มต้นของรูปแบบ และจำกัดจำนวนการจับคู่ - ทำให้ข้อมูลนำเข้าแบบไดนามิกปลอดภัยด้วย
QuoteMetaและจัดเก็บรูปแบบที่สร้างขณะโปรแกรมทำงานไว้ใน cache
package main
import (
"fmt"
"regexp"
)
var re = regexp.MustCompile("^\\d{4}$")
func main() {
for _, s := range []string{"1234", "12"} {
fmt.Println(s, re.MatchString(s))
}
}คำถามที่พบบ่อย
บทเรียน “เคล็ดลับด้านประสิทธิภาพ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “เคล็ดลับด้านประสิทธิภาพ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “เคล็ดลับด้านประสิทธิภาพ”
ใช้ regexp ที่คอมไพล์แล้วซ้ำ คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “เคล็ดลับด้านประสิทธิภาพ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม
ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐาน regexp
- การค้นหาและแยกข้อมูล
- การแทนที่ข้อความ
- เคล็ดลับด้านประสิทธิภาพ