• 失了智的沫雨
    2018-11-11
    如果只看strings.Builder 和bytes.Buffer的String方法的话,strings.Builder 更高效一些。
    我们可以直接查看两个String方法的源代码,其中strings.Builder String方法中
    *(*string)(unsafe.Pointer(&b.buf)) 是直接取得buf的地址然后转换成string返回。
    而bytes.Buffer的String方法是 string(b.buf[b.off:])
     对buf 进行切片操作,我认为这比直接取址要花费更多的时间。
    测试函数:
    func BenchmarkStrings(b *testing.B) {
        str := strings.Builder{}/bytes.Buffer{}
        str.WriteString("test")
        for i := 0; i < b.N; i++ {
            str.String()
        }
    }
    结果为
    BenchmarkStrings-8     2000000000     0.66 ns/op
    BenchmarkBuffer-8     300000000     5.64 ns/op
    所以strings.Builder的String方法更高效
    展开
     1
     14
  • 骏Jero
    2018-11-09
    读了老师的两篇文章,strings.Builder更多是拼接数据和以及拼接完成后的读取使用上应该更适合。而buffer更为动态接受和读取数据时,更为高效。
    
     2
  • 🤔
    2019-04-26
    https://github.com/golang/go/blob/master/src/strings/builder_test.go#L319-L366

    发现最后的问题,Go 的标准库中,已经给出了相关的测试代码了。
    
     1
  • 1thinc0
    2018-11-16
    bytes.Buffer 值的 String() 方法在转换时采用了指针 *(*string)(unsafe.Pointer(&b.buf)),更节省时间和内存
    
     1
  • cygnus
    2018-11-13
    ```
    func (b *Buffer) grow(n int) int {
            ......
        // Restore b.off and len(b.buf).
        b.off = 0
        b.buf = b.buf[:m+n]
        return m

    func (b *Buffer) Grow(n int) {
        if n < 0 {
            panic("bytes.Buffer.Grow: negative count")
        }
        m := b.grow(n)
        b.buf = b.buf[:m]
    }
    ```
    请问下老师,bytes.Buffer里grow函数返回前做过一次切片b.buf = b.buf[:m+n],返回后在Grow函数又做了一次切片b.buf = b.buf[:m],这样做的目的是什么呢?感觉有点冗余
    展开
    
     1
  • 疯琴
    2020-01-07
    请问老师,用 bytes.Buffer 而不用字节切片是因为它有计数器和一些方法使得操作更方便,还有高效的扩容策略么。这么说对么?

    作者回复: 因为有缓冲区啊,比较适合分步构建字符串值。

    
    
  • 窗外
    2019-08-11
    老师你好,为什么我本地的src/runtime包下的stringtoslicebyte方法里面tmpBuf的默认长度是32。
    所以文中例子,输出的容量是32

    作者回复: 你可以把前因后果都摆上来。这篇文章里有 tmpBuf 吗?

     1
    
  • rename
    2019-07-14
    如果当前内容容器的容量的一半,仍然大于或等于其现有长度再加上所需的字节数的和,即:cap(b.buf)/2 >= len(b.buf)+need
    这边len(b.buf)用b.Len()似乎更准确?才是获取未读部分的实际长度

    作者回复: 当然是要看 buf 本身的长度了。这是 bytes.Buffer 内部的算法,你可以看一看源码。

     1
    
  • 嘎嘎
    2019-03-15
    源码里给了推荐的构建方法
    // To build strings more efficiently, see the strings.Builder type.
    func (b *Buffer) String() string {
        if b == nil {
            // Special case, useful in debugging.
            return "<nil>"
        }
        return string(b.buf[b.off:])
    }
    展开

    作者回复: 这个Buffer类型比strings.Builder类型出现要早。我觉得后者质量更高一些。你可以参看一下后者的String方法。

    
    
  • 虢國技醬
    2019-03-06
    打卡
    
    
我们在线,来聊聊吧