Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: strings: add Builder.Available and Builder.AvailableBuffer #62209

Closed
korzhao opened this issue Aug 22, 2023 · 4 comments
Closed

proposal: strings: add Builder.Available and Builder.AvailableBuffer #62209

korzhao opened this issue Aug 22, 2023 · 4 comments
Labels
Milestone

Comments

@korzhao
Copy link
Contributor

korzhao commented Aug 22, 2023

I propose adding functions Builder.Available and Builder.AvailableBuffer.

// AvailableBuffer returns an empty buffer with b.Available() capacity.
func (b *Builder) AvailableBuffer() []byte

// Available returns how many bytes are unused in the buffer.
func (b *Builder) Available() int

In recent years, we have added many append-like APIs. It would be great if strings.Builder could benefit from it.

One scenario I can think of is base64 encoding:

For example:

// EncodeToString returns the base64 encoding of src.
func (enc *Encoding) EncodeToString(src []byte) string {
	build := strings.Builder{}
	build.Grow(enc.EncodedLen(len(src)))

	buf := build.AvailableBuffer()
	buf = enc.AppendEncode(buf, src)

	build.Write(buf)
	return build.String()
}

Bench:

benchmark                      old ns/op     new ns/op     delta
BenchmarkEncodeToString-10     6115          4999          -18.25%

benchmark                      old MB/s     new MB/s     speedup
BenchmarkEncodeToString-10     1339.73      1638.63      1.22x

benchmark                      old allocs     new allocs     delta
BenchmarkEncodeToString-10     2              1              -50.00%

benchmark                      old bytes     new bytes     delta
BenchmarkEncodeToString-10     24576         12288         -50.00%
@gopherbot gopherbot added this to the Proposal milestone Aug 22, 2023
@mateusz834
Copy link
Member

returning []byte from AvailableBuffer is not safe, this will allow modification of strings without unsafe package.

@korzhao
Copy link
Contributor Author

korzhao commented Aug 22, 2023

returning []byte from AvailableBuffer is not safe, this will allow modification of strings without unsafe package.

It should be clarified that 'AvailableBuffer' returns the unused slice buf[len(buf):].

For the slice buf[0:len(buf)] being used, we cannot modify them using existing APIs.
@mateusz834

@mateusz834
Copy link
Member

mateusz834 commented Aug 22, 2023

Yeah, but you can:

var s strings.Builder
s.Grow(16)
buf := s.AvailableBuffer()
s.Write([]byte("test"))
str := s.String()
copy(buf, []byte("oops"))
fmt.Println(str == "test") // false

@korzhao
Copy link
Contributor Author

korzhao commented Aug 22, 2023

Thanks. I hadn't thought of that.
@mateusz834

@korzhao korzhao closed this as completed Aug 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants