mirror of
https://github.com/PuerkitoBio/goquery.git
synced 2026-10-19 16:15:33 +00:00
perf: replace rxClassTrim regexp with strings.Replacer
The regex [\t\r\n] only does single-byte substitution, which is exactly what strings.Replacer's byteReplacer is optimized for. This removes the regexp dependency from property.go and drops the redundant ContainsAny fast-path guard in HasClass, since byteReplacer already returns the original string unchanged (no allocation) when nothing matches. Benchmark shows ~18% improvement on HasClass with 0 allocs either way.
This commit is contained in:
+11
-9
@@ -1,13 +1,12 @@
|
||||
package goquery
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
var rxClassTrim = regexp.MustCompile("[\t\r\n]")
|
||||
var classTrimReplacer = strings.NewReplacer("\t", " ", "\r", " ", "\n", " ")
|
||||
|
||||
// Attr gets the specified attribute's value for the first element in the
|
||||
// Selection. To get the value for each element individually, use a looping
|
||||
@@ -140,9 +139,14 @@ func (s *Selection) AddClass(class ...string) *Selection {
|
||||
func (s *Selection) HasClass(class string) bool {
|
||||
class = " " + class + " "
|
||||
for _, n := range s.Nodes {
|
||||
classes, _ := getClassesAndAttr(n, false)
|
||||
if strings.Contains(classes, class) {
|
||||
return true
|
||||
if n.Type != html.ElementNode {
|
||||
continue
|
||||
}
|
||||
if attr := getAttributePtr("class", n); attr != nil {
|
||||
val := classTrimReplacer.Replace(attr.Val)
|
||||
if strings.Contains(" "+val+" ", class) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
@@ -243,17 +247,15 @@ func getClassesAndAttr(n *html.Node, create bool) (classes string, attr *html.At
|
||||
|
||||
if attr == nil {
|
||||
classes = " "
|
||||
} else if strings.ContainsAny(attr.Val, "\t\r\n") {
|
||||
classes = rxClassTrim.ReplaceAllString(" "+attr.Val+" ", " ")
|
||||
} else {
|
||||
classes = " " + attr.Val + " "
|
||||
classes = classTrimReplacer.Replace(" " + attr.Val + " ")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getClassesSlice(classes string) []string {
|
||||
return strings.Split(rxClassTrim.ReplaceAllString(" "+classes+" ", " "), " ")
|
||||
return strings.Split(classTrimReplacer.Replace(" "+classes+" "), " ")
|
||||
}
|
||||
|
||||
func removeAttr(n *html.Node, attrName string) {
|
||||
|
||||
Reference in New Issue
Block a user