perf: add sync pool for template struct

This commit is contained in:
Jan De Dobbeleer 2024-08-06 08:13:13 +02:00 committed by Jan De Dobbeleer
parent e7cbbde984
commit 84ac954c86
3 changed files with 62 additions and 19 deletions

View file

@ -217,9 +217,8 @@ func (segment *Segment) SetText() {
}
func (segment *Segment) string() string {
var templatesResult string
if !segment.Templates.Empty() {
templatesResult = segment.Templates.Resolve(segment.writer, segment.env, "", segment.TemplatesLogic)
templatesResult := segment.Templates.Resolve(segment.writer, segment.env, "", segment.TemplatesLogic)
if len(segment.Template) == 0 {
return templatesResult
}
@ -233,7 +232,6 @@ func (segment *Segment) string() string {
Template: segment.Template,
Context: segment.writer,
Env: segment.env,
TemplatesResult: templatesResult,
}
text, err := tmpl.Render()

View file

@ -34,10 +34,12 @@ func (l List) Join(context any, env runtime.Environment) string {
if len(l) == 0 {
return ""
}
txtTemplate := &Text{
Context: context,
Env: env,
}
var buffer strings.Builder
for _, tmpl := range l {
txtTemplate.Template = tmpl
@ -45,8 +47,10 @@ func (l List) Join(context any, env runtime.Environment) string {
if err != nil || len(strings.TrimSpace(value)) == 0 {
continue
}
buffer.WriteString(value)
}
return buffer.String()
}
@ -54,10 +58,12 @@ func (l List) FirstMatch(context any, env runtime.Environment, defaultValue stri
if len(l) == 0 {
return defaultValue
}
txtTemplate := &Text{
Context: context,
Env: env,
}
for _, tmpl := range l {
txtTemplate.Template = tmpl
value, err := txtTemplate.Render()
@ -66,5 +72,6 @@ func (l List) FirstMatch(context any, env runtime.Environment, defaultValue stri
}
return value
}
return defaultValue
}

View file

@ -5,6 +5,7 @@ import (
"errors"
"reflect"
"strings"
"sync"
"text/template"
"github.com/jandedobbeleer/oh-my-posh/src/cache"
@ -50,32 +51,68 @@ var (
shell string
tmplFunc = template.New("cache").Funcs(funcMap())
contextPool = sync.Pool{
New: func() any {
return &context{}
},
}
buffPool = sync.Pool{
New: func() any {
return &buff{}
},
}
)
type buff bytes.Buffer
func (b *buff) release() {
(*bytes.Buffer)(b).Reset()
buffPool.Put(b)
}
func (b *buff) Write(p []byte) (n int, err error) {
return (*bytes.Buffer)(b).Write(p)
}
func (b *buff) String() string {
return (*bytes.Buffer)(b).String()
}
type Text struct {
Template string
Context any
Env runtime.Environment
TemplatesResult string
}
type Data any
type Context struct {
type context struct {
*cache.Template
// Simple container to hold ANY object
Data
Templates string
initialized bool
}
func (c *Context) init(t *Text) {
func (c *context) init(t *Text) {
c.Data = t.Context
c.Templates = t.TemplatesResult
if tmplCache := t.Env.TemplateCache(); tmplCache != nil {
c.Template = tmplCache
if c.initialized {
return
}
if tmplCache := t.Env.TemplateCache(); tmplCache != nil {
c.Template = tmplCache
}
c.initialized = true
}
func (c *context) release() {
c.Data = nil
contextPool.Put(c)
}
func (t *Text) Render() (string, error) {
@ -95,11 +132,12 @@ func (t *Text) Render() (string, error) {
return "", errors.New(InvalidTemplate)
}
context := &Context{}
context := contextPool.Get().(*context)
context.init(t)
defer context.release()
buffer := new(bytes.Buffer)
defer buffer.Reset()
buffer := buffPool.Get().(*buff)
defer buffer.release()
err = tmpl.Execute(buffer, context)
if err != nil {