阅读golang bufio文档
This commit is contained in:
@@ -72,6 +72,8 @@
|
||||
- [time.Duration](#timeduration)
|
||||
- [Bufio](#bufio)
|
||||
- [Buffered Reader](#buffered-reader)
|
||||
- [Buffered Writer](#buffered-writer)
|
||||
- [修改缓冲区大小](#修改缓冲区大小)
|
||||
- [syntax](#syntax)
|
||||
- [iota](#iota)
|
||||
|
||||
@@ -1568,6 +1570,151 @@ ok git.kazusa.red/asahi/bufio 9.254s
|
||||
可知,带缓冲场景下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`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user