Skip to content

Conversation

@tetromino
Copy link
Collaborator

@tetromino tetromino commented Oct 23, 2025

@tetromino tetromino requested a review from adonovan October 23, 2025 21:36
Copy link
Collaborator

@adonovan adonovan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks.

lib/json/json.go Outdated
if err != nil {
return nil, err
}
buf := new(bytes.Buffer)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strings.Builder

will save an allocation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

json.Encode is built around growing a bytes.Buffer; I think making a version that appends to a strings.Builder is a bit out of scope of this pr (although potentially useful).

But you are right that allocating buf via new is a waste - fixed.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant was that bytes.Buffer is more efficient when you want the final result as a []byte slice (buf.Bytes()), and strings.Builder is more efficient when you want the result as a string (buf.String()). (The difference is one allocation of a copy in each case.)

Since here we want String, we should use strings.Builder; no other change is needed.

BTW, allocating buf via new(T) or var x T in fact makes no difference: all that matters is whether the address of the variable escapes, which is independent of how you create the variable (unlike C++, where the syntax determines heap vs. stack allocation).

Copy link
Collaborator Author

@tetromino tetromino Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently starlark-go relies on json.Indent for indenting, which writes its output into a *bytes.Buffer: https://pkg.go.dev/encoding/json#Indent

Maybe I'm missing something obvious, but I don't see how it can be efficiently made to write into a strings.Builder.

BTW, allocating buf via new(T) or var x T in fact makes no difference

Thank you for correcting my wrong mental model of Go's allocator!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, good point, the standard encoding/json package is indeed a constraint. This is fine.

@adonovan adonovan merged commit 7849196 into google:master Oct 29, 2025
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Please add json.encode_indent

2 participants