从前面截断缓冲区

huangapple go评论82阅读模式
英文:

Truncate buffer from front

问题

bytes.Buffer对象有一个Truncate(n int)方法,用于丢弃除了前n个字节之外的所有内容。

我需要的是完全相反的操作 - 保留最后n个字节。

我可以这样做:

b := buf.Bytes()
buf.Reset()
buf.Write(b[len(b)-n:])

但我不确定这样做是否会高效地重用切片。

是否有更好的选择?

英文:

The bytes.Buffer object has a Truncate(n int) method to discard all but the first n bytes.

I'd need the exact inverse of that - keeping the last n bytes.

I could do the following

b := buf.Bytes()
buf.Reset()
buf.Write(b[offset:])

but I'm not sure if this will re-use the slice efficiently.

Are there better options?

答案1

得分: 1

有两种选择:

  • 你提供的解决方案,允许重用前面的 'offset' 字节。
  • 创建一个 bytes.NewBuffer(b[offset:]) 并使用它。这样做不会在你使用新缓冲区之前释放前面的 'offset' 字节,但可以避免复制的开销。
英文:

There are two alternatives:

  • The solution you give, which allows the first 'offset' bytes to be reused.
  • Create a bytes.NewBuffer(b[offset:]) and use that. This will not allow the first 'offset' bytes to be collected until you're done with the new buffer, but it avoids the cost of copying.

答案2

得分: 0

bytes.Buffer处理缓冲区管理。内部的grow方法会将数据向下滑动。使用Next方法。例如,

package main

import (
	"bytes"
	"fmt"
)

func main() {
	var buf bytes.Buffer
	for i := 0; i < 8; i++ {
		buf.WriteByte(byte(i))
	}
	fmt.Println(buf.Len(), buf.Bytes())
	n := buf.Len() / 2

	// 保留最后n个字节。
	if n > buf.Len() {
		n = buf.Len()
	}
	buf.Next(buf.Len() - n)

	fmt.Println(buf.Len(), buf.Bytes())
}

输出:

8 [0 1 2 3 4 5 6 7]
4 [4 5 6 7]
英文:

Let bytes.Buffer handle the buffer management. The internal grow method slides the data down. Use the Next method. For example,

package main

import (
	&quot;bytes&quot;
	&quot;fmt&quot;
)

func main() {
	var buf bytes.Buffer
	for i := 0; i &lt; 8; i++ {
		buf.WriteByte(byte(i))
	}
	fmt.Println(buf.Len(), buf.Bytes())
	n := buf.Len() / 2

	// Keep last n bytes.
	if n &gt; buf.Len() {
		n = buf.Len()
	}
	buf.Next(buf.Len() - n)

	fmt.Println(buf.Len(), buf.Bytes())
}

Output:

8 [0 1 2 3 4 5 6 7]
4 [4 5 6 7]

答案3

得分: 0

我认为你的想法存在问题,因为“从开头截断缓冲区”是不可能的,因为内存分配器会分配完整的内存块,并且没有机制将已分配的块分割成一组“子块”,这实际上就是你所要求的。因此,为了支持“从开头截断”,bytes.Buffer的实现将不得不分配一个较小的缓冲区,将“尾部”移动到那里,然后标记原始缓冲区以供重用。

这自然而然地引出了另一个想法:使用两个(或更多)缓冲区。它们可以分别分配,并且在你的算法中被视为相邻的,或者你可以使用自定义分配:先分配一个大的切片,然后将其切片两次或多次以产生几个物理上相邻的缓冲区,或者在其上滑动一个或多个“窗口”切片。当然,这意味着需要实现一个自定义的数据结构...

英文:

I reckon the problem with your idea is that "truncating the buffer from its start" is impossible simply because the memory allocator allocates memory in full chunks and there's no machinery in it to split an already allocated chunk into a set of "sub chunks" &mdash; essentially what you're asking for. So to support "trimming from the beginning" the implementation of bytes.Buffer would have to allocate a smaller buffer, move the "tail" there and then mark the original buffer for reuse.

This naturally leads us to another idea: use two (or more) buffers. They might either be allocated separately and treated as adjacent by your algorythms or you might use custom allocation: allocate one big slice and then reslice it twice or more times to produce several physically adjacent buffers, or slide one or more "window" slices over it. This means implementing a custom data structure of course&hellip;

huangapple
  • 本文由 发表于 2013年12月9日 00:49:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/20455995.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定