bytebuf

Example of how CL133375 can be utilized to mitigate Go escape analysis limitations.

  • 所有者: intel-go/bytebuf
  • 平台:
  • 許可證: BSD 3-clause "New" or "Revised" License
  • 分類:
  • 主題:
  • 喜歡:
    0
      比較:

Github星跟蹤圖

bytebuf

UPDATE: This implementation is deprecated as the patch is merged to the Go mainline (https://golang.org/cl/133715)

Example of how CL133375 cmd/compile/internal/gc: handle array slice self-assign in esc.go
can be utilized to mitigate Go escape analysis limitations.

It shows how to fix problem described in
cmd/compile, bytes: bootstrap array causes bytes.Buffer to always be heap-allocated
using brand new escape analysis pattern.

Implementation difference

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.

Performance comparison before bytes.Buffer optimization in CL133715

These results provided only for historical reference.

Given this code:

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

Where s is:, Label, Data, -------, ------, empty, empty string, 5, 5-byte string, 64, 64-byte string, 128, 128-byte string, 1024, 1024-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/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/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/1024-8 3.00 ± 0% 2.00 ± 0% -33.33% (p=0.000 n=10+10)


## Performance comparison after [bytes.Buffer optimization in CL133715](https://golang.org/cl/133715)

After improvements to `bytes.Buffer` from the standard library and
updated tests that do `bytes.NewBuffer(make([]byte, 0, 64))`,
results are mostly in favor of `bytes.Buffer`.

Also note that `bytes.Buffer` makes it possible to have a custom size
stack-allocated slice as a bootstrap storage, so it's overall a
better choice.

name old time/op new time/op delta
String/empty-8 23.8ns ± 0% 25.7ns ± 0% +8.04% (p=0.000 n=8+8)
String/5-8 59.6ns ± 1% 53.4ns ± 1% -10.32% (p=0.000 n=10+10)
String/64-8 102ns ±12% 95ns ± 4% -6.94% (p=0.001 n=10+8)
String/1024-8 745ns ± 0% 768ns ± 1% +3.08% (p=0.000 n=9+8)

name old alloc/op new alloc/op delta
String/empty-8 0.00B 0.00B ~ (all equal)
String/5-8 5.00B ± 0% 5.00B ± 0% ~ (all equal)
String/64-8 64.0B ± 0% 64.0B ± 0% ~ (all equal)
String/1024-8 2.05kB ± 0% 2.18kB ± 0% +6.25% (p=0.000 n=10+10)

name old allocs/op new allocs/op delta
String/empty-8 0.00 0.00 ~ (all equal)
String/5-8 1.00 ± 0% 1.00 ± 0% ~ (all equal)
String/64-8 1.00 ± 0% 1.00 ± 0% ~ (all equal)
String/1024-8 2.00 ± 0% 2.00 ± 0% ~ (all equal)

主要指標

概覽
名稱與所有者intel-go/bytebuf
主編程語言Go
編程語言Go (語言數: 1)
平台
許可證BSD 3-clause "New" or "Revised" License
所有者活动
創建於2018-09-04 18:51:32
推送於2018-09-21 20:49:52
最后一次提交2018-09-21 15:49:51
發布數0
用户参与
星數494
關注者數21
派生數20
提交數23
已啟用問題?
問題數4
打開的問題數0
拉請求數3
打開的拉請求數0
關閉的拉請求數0
项目设置
已啟用Wiki?
已存檔?
是復刻?
已鎖定?
是鏡像?
是私有?