mirror of
https://github.com/PuerkitoBio/goquery
synced 2025-09-26 21:01:21 +08:00
increase performance by migrating from bytes.Buffer to strings.Builder
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
package goquery
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkMetalReviewExample(b *testing.B) {
|
||||
var n int
|
||||
var buf bytes.Buffer
|
||||
var builder strings.Builder
|
||||
|
||||
b.StopTimer()
|
||||
doc := loadDoc("metalreview.html")
|
||||
@@ -27,12 +27,12 @@ func BenchmarkMetalReviewExample(b *testing.B) {
|
||||
if score, e = strconv.ParseFloat(s.Find(".score").Text(), 64); e != nil {
|
||||
// Not a valid float, ignore score
|
||||
if n <= 4 {
|
||||
buf.WriteString(fmt.Sprintf("Review %d: %s - %s.\n", i, band, title))
|
||||
builder.WriteString(fmt.Sprintf("Review %d: %s - %s.\n", i, band, title))
|
||||
}
|
||||
} else {
|
||||
// Print all, including score
|
||||
if n <= 4 {
|
||||
buf.WriteString(fmt.Sprintf("Review %d: %s - %s (%2.1f).\n", i, band, title, score))
|
||||
builder.WriteString(fmt.Sprintf("Review %d: %s - %s (%2.1f).\n", i, band, title, score))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
13
property.go
13
property.go
@@ -1,7 +1,6 @@
|
||||
package goquery
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
@@ -60,14 +59,14 @@ func (s *Selection) SetAttr(attrName, val string) *Selection {
|
||||
// Text gets the combined text contents of each element in the set of matched
|
||||
// elements, including their descendants.
|
||||
func (s *Selection) Text() string {
|
||||
var buf bytes.Buffer
|
||||
var builder strings.Builder
|
||||
|
||||
// Slightly optimized vs calling Each: no single selection object created
|
||||
var f func(*html.Node)
|
||||
f = func(n *html.Node) {
|
||||
if n.Type == html.TextNode {
|
||||
// Keep newlines and spaces, like jQuery
|
||||
buf.WriteString(n.Data)
|
||||
builder.WriteString(n.Data)
|
||||
}
|
||||
if n.FirstChild != nil {
|
||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
||||
@@ -79,7 +78,7 @@ func (s *Selection) Text() string {
|
||||
f(n)
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// Size is an alias for Length.
|
||||
@@ -97,16 +96,16 @@ func (s *Selection) Length() int {
|
||||
func (s *Selection) Html() (ret string, e error) {
|
||||
// Since there is no .innerHtml, the HTML content must be re-created from
|
||||
// the nodes using html.Render.
|
||||
var buf bytes.Buffer
|
||||
var builder strings.Builder
|
||||
|
||||
if len(s.Nodes) > 0 {
|
||||
for c := s.Nodes[0].FirstChild; c != nil; c = c.NextSibling {
|
||||
e = html.Render(&buf, c)
|
||||
e = html.Render(&builder, c)
|
||||
if e != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
ret = buf.String()
|
||||
ret = builder.String()
|
||||
}
|
||||
|
||||
return
|
||||
|
21
utilities.go
21
utilities.go
@@ -1,8 +1,8 @@
|
||||
package goquery
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
@@ -26,13 +26,12 @@ var nodeNames = []string{
|
||||
// Go's net/html package defines the following node types, listed with
|
||||
// the corresponding returned value from this function:
|
||||
//
|
||||
// ErrorNode : #error
|
||||
// TextNode : #text
|
||||
// DocumentNode : #document
|
||||
// ElementNode : the element's tag name
|
||||
// CommentNode : #comment
|
||||
// DoctypeNode : the name of the document type
|
||||
//
|
||||
// ErrorNode : #error
|
||||
// TextNode : #text
|
||||
// DocumentNode : #document
|
||||
// ElementNode : the element's tag name
|
||||
// CommentNode : #comment
|
||||
// DoctypeNode : the name of the document type
|
||||
func NodeName(s *Selection) string {
|
||||
if s.Length() == 0 {
|
||||
return ""
|
||||
@@ -77,11 +76,11 @@ func Render(w io.Writer, s *Selection) error {
|
||||
// because this is not a jQuery method (in javascript-land, this is
|
||||
// a property provided by the DOM).
|
||||
func OuterHtml(s *Selection) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
if err := Render(&buf, s); err != nil {
|
||||
var builder strings.Builder
|
||||
if err := Render(&builder, s); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buf.String(), nil
|
||||
return builder.String(), nil
|
||||
}
|
||||
|
||||
// Loop through all container nodes to search for the target node.
|
||||
|
Reference in New Issue
Block a user