gobuffalo / plush

The powerful template system that Go needs
MIT License
895 stars 57 forks source link

bug: high memory usage when calling compile() #186

Closed Mido-sys closed 1 month ago

Mido-sys commented 1 month ago

Description

Description

We noticed high memory usage for this function under compiler.go: due to converting bytes to string.

func (c *compiler) compile() (string, error) {
    bb := &bytes.Buffer{}

    for _, stmt := range c.program.Statements {
        var res interface{}
        var err error

        switch node := stmt.(type) {
        case *ast.ReturnStatement:
            res, err = c.evalReturnStatement(node)

        case *ast.ExpressionStatement:
            if h, ok := node.Expression.(*ast.HTMLLiteral); ok {
                res = template.HTML(h.Value)
            } else {
                _, err = c.evalExpression(node.Expression)
            }
        case *ast.LetStatement:
            res, err = c.evalLetStatement(node)
        }

        if err != nil {
            s := stmt
            if c.curStmt != nil {
                s = c.curStmt
            }
            return "", fmt.Errorf("line %d: %w", s.T().LineNumber, err)
        }

        c.write(bb, res)
    }

    return bb.String(), nil
}

The bytes.Buffer to string conversion requires memory allocation. A better solution is to drop bytes.Buffer and just use strings.Builder instead. strings.Builder uses a more optimized code to convert to string

Mido-sys commented 1 month ago

Hello @paganotoni , I pushed a fix.