Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

14 Commits

Repository files navigation

bytebuf

Replacement for bytes.Buffer that you can use in a performance-sensitive parts or your Go programs.

For explanation why this package is needed, see rationale.

Quick start / Installation

go get -u github.com/intel-go/bytebuf

The only difference from bytes.Buffer is explicit constructor:

buf:=bytebuf.New() // Can't just use zero value// Now can use as an ordinary bytes.Buffer:buf.WriteString("123")
buf.Write([]byte("456")

Performance

Given this code:

buf.Write(s)
globalString = buf.String()

Where s is:

LabelData
empty""
5"Intel"
6464-byte string
128128-byte string
10241024-byte string
name old time/op new time/op delta
String/empty-8 138ns ±13% 24ns ± 0% -82.94% (p=0.000 n=10+8)
String/5-8 186ns ±11% 60ns ± 1% -67.82% (p=0.000 n=10+10)
String/64-8 225ns ±10% 108ns ± 6% -52.26% (p=0.000 n=10+10)
String/128-8 474ns ±17% 338ns ±13% -28.57% (p=0.000 n=10+10)
String/1024-8 889ns ± 0% 740ns ± 1% -16.78% (p=0.000 n=9+10)
name old alloc/op new alloc/op delta
String/empty-8 112B ± 0% 0B -100.00% (p=0.000 n=10+10)
String/5-8 117B ± 0% 5B ± 0% -95.73% (p=0.000 n=10+10)
String/64-8 176B ± 0% 64B ± 0% -63.64% (p=0.000 n=10+10)
String/128-8 368B ± 0% 256B ± 0% -30.43% (p=0.000 n=10+10)
String/1024-8 2.16kB ± 0% 2.05kB ± 0% -5.19% (p=0.000 n=10+10)
name old allocs/op new allocs/op delta
String/empty-8 1.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10)
String/5-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
String/64-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
String/128-8 3.00 ± 0% 2.00 ± 0% -33.33% (p=0.000 n=10+10)
String/1024-8 3.00 ± 0% 2.00 ± 0% -33.33% (p=0.000 n=10+10)

Note: it requres CL133375 to be applied to your Go compiler.

Implementation difference / Rationale

The whole implementation difference can be described as:

type Buffer struct {
buf []byte // contents are the bytes buf[off : len(buf)]
off int // read at &buf[off], write at &buf[len(buf)]
- bootstrap [64]byte // memory to hold first slice; helps small buffers avoid allocation.+ bootstrap *[64]byte // memory to hold first slice; helps small buffers avoid allocation.
lastRead readOp // last read operation, so that Unread* can work correctly.
}

With updated escape analysis, it's possible to actually take benefits of bootstrap array, but only if it's not "inlined" into Buffer object. So, we need a pointer to array instead of normal array.

This makes it impossible to use zero value though, hence New function. Unfortunately, it means that we can't merge this into golang bytes package, it would be a breaking change in package API.

If you're interested in bootstrap array problem, take a look at cmd/compile, bytes: bootstrap array causes bytes.Buffer to always be heap-allocated.

About

Replacement for bytes.Buffer that you can use in a performace-sensitive parts or your Go programs

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages