From 93441d04fd3a9f4eedad13ee4d6d58cd4b75ffdc Mon Sep 17 00:00:00 2001 From: asahi Date: Sat, 18 Jan 2025 01:45:05 +0800 Subject: [PATCH] =?UTF-8?q?=E9=98=85=E8=AF=BBbuffered=20io=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Golang/Golang Document.md | 95 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/Golang/Golang Document.md b/Golang/Golang Document.md index 016808b..be5ba21 100644 --- a/Golang/Golang Document.md +++ b/Golang/Golang Document.md @@ -70,6 +70,8 @@ - [compare time](#compare-time) - [Sub](#sub) - [time.Duration](#timeduration) + - [Bufio](#bufio) + - [Buffered Reader](#buffered-reader) - [syntax](#syntax) - [iota](#iota) @@ -1475,6 +1477,99 @@ const ( 2010-12-17 19:03:32 +0000 UTC ``` +## Bufio +`bufio`为golang中的一个包,提供了带缓冲的读写功能。 + +### Buffered Reader +如果要创建一个buffered reader,可以使用`bufio.NewReader`方法,该方法接受一个`io.Reader`作为参数,返回类型则是`*bufio.Reader`。 + +常用的`bufio.NewReader`的入参为`os.File`, `strings.Reader`, `bytes.Buffer`。 + +使用带缓冲区io和不带缓冲区io,针对`10M`的文件,性能差别如下所示。 + +测试文件如下,大小为`10M` +```bash +$ ls -lh random.file +-rw-r--r-- 1 Asahi 197609 10M Jan 18 01:24 random.file +``` + +带缓冲和不带缓冲代码如下: +```go +func CountWithoutBuf(filename string, b byte) (cnt uint64) { + file, err := os.OpenFile(filename, os.O_RDONLY, 0) + if err != nil { + panic(any(err)) + } + defer file.Close() + cnt = 0 + bs := []byte{0} + for { + _,err = file.Read(bs) + if err == io.EOF { + break + } else if err != nil { + panic(any(err)) + } else if bs[0] == b { + cnt++ + } + } + return +} + +func CountWithBuf(filename string, b byte) (cnt uint64) { + file, err := os.OpenFile(filename, os.O_RDONLY, 0) + if err != nil { + panic(any(err)) + } + defer file.Close() + cnt = 0 + bs := []byte{0} + br := bufio.NewReader(file) + for { + _,err = br.Read(bs) + if err == io.EOF { + break + } else if err != nil { + panic(any(err)) + } else if bs[0] == b { + cnt++ + } + } + return +} +``` + +benchmark测试代码如下: +```go +func BenchmarkCountWithBuf(b *testing.B) { + CountWithBuf(FileName, B) +} + +func BenchmarkCountWithoutBuf(b *testing.B) { + CountWithoutBuf(FileName, B) +} +``` +执行benchmark命令: +```bash +go test -bench=.* +``` + +测试结果返回如下: +``` +goos: windows +goarch: amd64 +pkg: git.kazusa.red/asahi/bufio +cpu: AMD Ryzen 9 7950X 16-Core Processor +BenchmarkCountWithBuf-32 1000000000 0.03209 ns/op +BenchmarkCountWithoutBuf-32 1 8937341700 ns/op +PASS +ok git.kazusa.red/asahi/bufio 9.254s +``` +可知,带缓冲场景下10M文件每次读取花费`0.03209 ns`,而不带缓冲按字节读取时每次读取花费`8.93s`。 + + + + ## syntax ### iota