Create and use a strings.Builder pool

This will probably make no big difference, but let's give it a try
This commit is contained in:
Jan-Lukas Else 2023-01-24 16:49:33 +01:00
parent 8c86c21d77
commit 720fc62919
7 changed files with 49 additions and 13 deletions

View File

@ -0,0 +1,23 @@
package builderpool
import (
"strings"
"sync"
)
var builderPool = sync.Pool{
New: func() any {
return new(strings.Builder)
},
}
func Get() *strings.Builder {
return builderPool.Get().(*strings.Builder)
}
func Put(bufs ...*strings.Builder) {
for _, buf := range bufs {
buf.Reset()
builderPool.Put(buf)
}
}

View File

@ -2,13 +2,13 @@ package highlighting
import ( import (
"io" "io"
"strings"
"github.com/yuin/goldmark" "github.com/yuin/goldmark"
"github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/renderer" "github.com/yuin/goldmark/renderer"
"github.com/yuin/goldmark/renderer/html" "github.com/yuin/goldmark/renderer/html"
"github.com/yuin/goldmark/util" "github.com/yuin/goldmark/util"
"go.goblog.app/app/pkgs/builderpool"
"github.com/alecthomas/chroma/v2" "github.com/alecthomas/chroma/v2"
chromahtml "github.com/alecthomas/chroma/v2/formatters/html" chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
@ -60,7 +60,8 @@ func (r *htmlRenderer) renderFencedCodeBlock(w util.BufWriter, source []byte, no
n := node.(*ast.FencedCodeBlock) n := node.(*ast.FencedCodeBlock)
// Read code block content. // Read code block content.
var buf strings.Builder buf := builderpool.Get()
defer builderpool.Put(buf)
for _, line := range n.Lines().Sliced(0, n.Lines().Len()) { for _, line := range n.Lines().Sliced(0, n.Lines().Len()) {
buf.Write(line.Value(source)) buf.Write(line.Value(source))
} }

View File

@ -12,6 +12,7 @@ import (
"github.com/araddon/dateparse" "github.com/araddon/dateparse"
"github.com/samber/lo" "github.com/samber/lo"
"go.goblog.app/app/pkgs/bufferpool" "go.goblog.app/app/pkgs/bufferpool"
"go.goblog.app/app/pkgs/builderpool"
) )
func (a *goBlog) checkPost(p *post, new bool) (err error) { func (a *goBlog) checkPost(p *post, new bool) (err error) {
@ -206,7 +207,8 @@ func (db *database) savePost(p *post, o *postCreationOptions) error {
db.pcm.Lock() db.pcm.Lock()
defer db.pcm.Unlock() defer db.pcm.Unlock()
// Build SQL // Build SQL
var sqlBuilder strings.Builder sqlBuilder := builderpool.Get()
defer builderpool.Put(sqlBuilder)
var sqlArgs = []any{dbNoCache} var sqlArgs = []any{dbNoCache}
// Start transaction // Start transaction
sqlBuilder.WriteString("begin;") sqlBuilder.WriteString("begin;")
@ -335,7 +337,8 @@ func (db *database) replacePostParam(path, param string, values []string) error
db.pcm.Lock() db.pcm.Lock()
defer db.pcm.Unlock() defer db.pcm.Unlock()
// Build SQL // Build SQL
var sqlBuilder strings.Builder sqlBuilder := builderpool.Get()
defer builderpool.Put(sqlBuilder)
var sqlArgs = []any{dbNoCache} var sqlArgs = []any{dbNoCache}
// Start transaction // Start transaction
sqlBuilder.WriteString("begin;") sqlBuilder.WriteString("begin;")
@ -385,7 +388,8 @@ type postsRequestConfig struct {
} }
func buildPostsQuery(c *postsRequestConfig, selection string) (query string, args []any) { func buildPostsQuery(c *postsRequestConfig, selection string) (query string, args []any) {
var queryBuilder strings.Builder queryBuilder := builderpool.Get()
defer builderpool.Put(queryBuilder)
// Selection // Selection
queryBuilder.WriteString("select ") queryBuilder.WriteString("select ")
queryBuilder.WriteString(selection) queryBuilder.WriteString(selection)
@ -519,7 +523,8 @@ func (d *database) loadPostParameters(posts []*post, parameters ...string) (err
} }
// Build query // Build query
sqlArgs := make([]any, 0) sqlArgs := make([]any, 0)
var queryBuilder strings.Builder queryBuilder := builderpool.Get()
defer builderpool.Put(queryBuilder)
queryBuilder.WriteString("select path, parameter, value from post_parameters where") queryBuilder.WriteString("select path, parameter, value from post_parameters where")
// Paths // Paths
queryBuilder.WriteString(" path in (") queryBuilder.WriteString(" path in (")
@ -691,7 +696,8 @@ group by name;
func (db *database) usesOfMediaFile(names ...string) (counts []int, err error) { func (db *database) usesOfMediaFile(names ...string) (counts []int, err error) {
sqlArgs := []any{dbNoCache} sqlArgs := []any{dbNoCache}
var nameValues strings.Builder nameValues := builderpool.Get()
defer builderpool.Put(nameValues)
for i, n := range names { for i, n := range names {
if i > 0 { if i > 0 {
nameValues.WriteString(", ") nameValues.WriteString(", ")

View File

@ -5,10 +5,10 @@ import (
"errors" "errors"
"io" "io"
"net/http" "net/http"
"strings"
"github.com/dgraph-io/ristretto" "github.com/dgraph-io/ristretto"
"github.com/samber/lo" "github.com/samber/lo"
"go.goblog.app/app/pkgs/builderpool"
"go.goblog.app/app/pkgs/contenttype" "go.goblog.app/app/pkgs/contenttype"
) )
@ -107,7 +107,8 @@ func (a *goBlog) getReactionsFromDatabase(path string) (map[string]int, error) {
// Get reactions // Get reactions
res, err, _ := a.reactionsSfg.Do(path, func() (any, error) { res, err, _ := a.reactionsSfg.Do(path, func() (any, error) {
// Build query // Build query
var sqlBuf strings.Builder sqlBuf := builderpool.Get()
defer builderpool.Put(sqlBuf)
sqlArgs := []any{} sqlArgs := []any{}
sqlBuf.WriteString("select reaction, count from reactions where path=? and reaction in (") sqlBuf.WriteString("select reaction, count from reactions where path=? and reaction in (")
sqlArgs = append(sqlArgs, path) sqlArgs = append(sqlArgs, path)

View File

@ -5,9 +5,9 @@ import (
"log" "log"
"net/url" "net/url"
"strconv" "strconv"
"strings"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"go.goblog.app/app/pkgs/builderpool"
) )
func (a *goBlog) initTelegram() { func (a *goBlog) initTelegram() {
@ -135,7 +135,8 @@ func (tg *configTelegram) generateHTML(title, fullURL, shortURL string) (html st
if !tg.enabled() { if !tg.enabled() {
return "" return ""
} }
var message strings.Builder message := builderpool.Get()
defer builderpool.Put(message)
if title != "" { if title != "" {
message.WriteString(tgbotapi.EscapeText(tgbotapi.ModeHTML, title)) message.WriteString(tgbotapi.EscapeText(tgbotapi.ModeHTML, title))
message.WriteString("\n\n") message.WriteString("\n\n")

View File

@ -6,6 +6,7 @@ import (
"time" "time"
"github.com/samber/lo" "github.com/samber/lo"
"go.goblog.app/app/pkgs/builderpool"
"go.goblog.app/app/pkgs/htmlbuilder" "go.goblog.app/app/pkgs/htmlbuilder"
) )
@ -64,7 +65,8 @@ func (a *goBlog) renderSummary(hb *htmlbuilder.HtmlBuilder, bc *configBlog, p *p
} }
// Show link to full post // Show link to full post
hb.WriteElementOpen("p") hb.WriteElementOpen("p")
var prefix strings.Builder prefix := builderpool.Get()
defer builderpool.Put(prefix)
if len(photos) > 0 { if len(photos) > 0 {
// Contains photos // Contains photos
prefix.WriteString("🖼️") prefix.WriteString("🖼️")

View File

@ -8,6 +8,7 @@ import (
"strings" "strings"
"time" "time"
"go.goblog.app/app/pkgs/builderpool"
"go.goblog.app/app/pkgs/contenttype" "go.goblog.app/app/pkgs/contenttype"
) )
@ -230,7 +231,8 @@ type webmentionsRequestConfig struct {
} }
func buildWebmentionsQuery(config *webmentionsRequestConfig) (query string, args []any) { func buildWebmentionsQuery(config *webmentionsRequestConfig) (query string, args []any) {
var queryBuilder strings.Builder queryBuilder := builderpool.Get()
defer builderpool.Put(queryBuilder)
queryBuilder.WriteString("select id, source, target, url, created, title, content, author, status from webmentions ") queryBuilder.WriteString("select id, source, target, url, created, title, content, author, status from webmentions ")
if config != nil { if config != nil {
queryBuilder.WriteString("where 1") queryBuilder.WriteString("where 1")