نصائح الأداء
أعد استخدام regexp المجمّعة
نصائح الأداء درس مجاني في Go Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 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 المترجمة آمنة للاستخدام المتزامن من عدة goroutines. ويمكن لمثيل عام واحد أن يخدمها جميعًا.
package main
import (
"fmt"
"regexp"
)
var re = regexp.MustCompile("go")
func main() {
fmt.Println(re.MatchString("golang"))
}تكون strings أسرع أحيانًا
بالنسبة إلى سلسلة فرعية حرفية ثابتة، تتفوق strings.Contains على regexp. استخدموا regexps فقط عندما تحتاجون إلى قوة الأنماط الفعلية.
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"))
}خزّنوا الأنماط المترجمة مؤقتًا
إذا أُنشئت الأنماط وقت التشغيل، فخزّنوا الأنماط المترجمة في خريطة مفاتيحها سلاسل الأنماط لتجنب ترجمة النمط نفسه مرة أخرى.
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؟
مراجعة: نصائح الأداء
لقد تعلمتم استخدام regexps بكفاءة:
- ترجموا النمط مرة واحدة باستخدام
MustCompileوأعيدوا استخدامه؛ فهو آمن للاستخدام المتزامن. - فضّلوا
stringsللسلاسل الفرعية الثابتة؛ واركزوا الأنماط؛ وحدّدوا عدد التطابقات. - اهربوا من الإدخال الديناميكي باستخدام
QuoteMetaوخزّنوا أنماط وقت التشغيل مؤقتًا.
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))
}
}الأسئلة الشائعة
هل درس «نصائح الأداء» مجاني؟
نعم — نص درس «نصائح الأداء» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Go Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Go Academy 4 دروس في المجموع.
ماذا ستتعلم في «نصائح الأداء»؟
أعد استخدام regexp المجمّعة تتمرن على Go Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Go Academy؟
لا تُشترط خبرة سابقة. Go Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «نصائح الأداء»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Go Academy هذا؟
نعم. كل درس في Go Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- أساسيات regexp
- العثور والاستخراج
- استبدال النصوص
- نصائح الأداء