0Pricing
Go Academy · บทเรียน

เคล็ดลับด้านประสิทธิภาพ

ใช้ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. พื้นฐาน regexp
  2. การค้นหาและแยกข้อมูล
  3. การแทนที่ข้อความ
  4. เคล็ดลับด้านประสิทธิภาพ
← กลับไปที่ Go Academy