阅读golang bufio文档

This commit is contained in:
asahi
2025-01-18 20:37:27 +08:00
parent 93441d04fd
commit bf8b6b42d3

View File

@@ -72,6 +72,8 @@
- [time.Duration](#timeduration) - [time.Duration](#timeduration)
- [Bufio](#bufio) - [Bufio](#bufio)
- [Buffered Reader](#buffered-reader) - [Buffered Reader](#buffered-reader)
- [Buffered Writer](#buffered-writer)
- [修改缓冲区大小](#修改缓冲区大小)
- [syntax](#syntax) - [syntax](#syntax)
- [iota](#iota) - [iota](#iota)
@@ -1568,6 +1570,151 @@ ok git.kazusa.red/asahi/bufio 9.254s
可知带缓冲场景下10M文件每次读取花费`0.03209 ns`,而不带缓冲按字节读取时每次读取花费`8.93s` 可知带缓冲场景下10M文件每次读取花费`0.03209 ns`,而不带缓冲按字节读取时每次读取花费`8.93s`
### Buffered Writer
类似于`bufio.NewReader`方法,可以通过`bufio.NewWriter`方法来创建一个buffered writer该方法接受`io.Writer`作为参数。
通常,可以将`os.File, stirngs.Builder, bytes.Buffer`作为参数传入。
在写入大小为50M的文件时其性能测试如下.
带缓冲和不带缓冲的代码实现
```go
func WriteToFileWithoutBuf(filename string, n uint32, generate func () []byte) (err error) {
file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0740)
if err != nil {
return
}
defer file.Close()
for i := 0; uint32(i) < n; i++ {
_, err = file.Write(generate())
if err != nil {
break
}
}
return
}
func WriteToFileWithBuf(filename string, n uint32, generate func () []byte) (err error) {
file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0740)
if err != nil {
return
}
defer file.Close()
w := bufio.NewWriter(file)
for i := 0; uint32(i) < n; i++ {
_, err = w.Write(generate())
if err != nil {
break
}
}
defer func(w *bufio.Writer) {
err := w.Flush()
if err != nil {
}
}(w)
return
}
```
benchmark代码如下所示
```go
func BenchmarkWriteToFileWithBuf(b *testing.B) {
if err := WriteToFileWithBuf(WriteFileName, 1024*1024*10, generateCharsSlice); err != nil {
panic(any(err))
}
}
func BenchmarkWriteToFileWithoutBuf(b *testing.B) {
if err := WriteToFileWithoutBuf(WriteFileName, 1024*1024*10, generateCharsSlice); err != nil {
panic(any(err))
}
}
func generateCharsSlice() []byte {
return []byte("asahi")
}
```
执行benmark命令进行测试
```bash
go test -bench=BenchmarkWriteToFile.*
```
测试结果如下所示:
```go
goos: windows
goarch: amd64
pkg: git.kazusa.red/asahi/bufio
cpu: AMD Ryzen 9 7950X 16-Core Processor
BenchmarkWriteToFileWithBuf-32 1000000000 0.1407 ns/op
BenchmarkWriteToFileWithoutBuf-32 1 13251963400 ns/op
PASS
ok git.kazusa.red/asahi/bufio 14.945s
```
易知当使用带缓冲版本时50M大小的文件写入事件为`0.1407ns`,而当使用不带缓冲的操作时,写入时间则需要花费`13s`
### 修改缓冲区大小
默认情况下,通过`NewReader`, `NewWriter`方法生成的buffered reader或writer其缓冲区大小默认为`4096`字节。
当想要修改缓冲区大小是,可以使用`NewReaderSize`方法,该方法额外接受一个定义缓冲区大小的参数。
代码如下
```go
func WriteToFileWithBufSize(filename string, n uint32, bufSize int, generate func() []byte) (err error) {
file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0740)
if err != nil {
return
}
defer file.Close()
w := bufio.NewWriterSize(file, bufSize)
for i := 0; uint32(i) < n; i++ {
_, err = w.Write(generate())
if err != nil {
break
}
}
defer func(w *bufio.Writer) {
err := w.Flush()
if err != nil {
}
}(w)
return
}
```
测试代码如下:
```go
func BenchmarkWriteToFileWith4KBuf(b *testing.B) {
if err := WriteToFileWithBufSize(WriteFileName, 1024*1024*10, 4096, generateCharsSlice); err != nil {
panic(any(err))
}
}
func BenchmarkWriteToFileWith128BytesBuf(b *testing.B) {
if err := WriteToFileWithBufSize(WriteFileName, 1024*1024*10, 128, generateCharsSlice); err != nil {
panic(any(err))
}
}
```
benchmark命令如下
```bash
go test -bench="BenchmarkWriteToFileWith(4K|128Bytes)Buf"
```
benchmark结果如下
```go
goos: windows
goarch: amd64
pkg: git.kazusa.red/asahi/bufio
cpu: AMD Ryzen 9 7950X 16-Core Processor
BenchmarkWriteToFileWith4KBuf-32 1000000000 0.1383 ns/op
BenchmarkWriteToFileWith128BytesBuf-32 1000000000 0.6549 ns/op
PASS
ok git.kazusa.red/asahi/bufio 26.042s
```
易知当读写50M文件时缓冲区大小为4096时每次写操作耗时`0.1383ns`而将缓冲区修改为128大小后每次写操作耗时增加到`0.65ns`