go - 如何有效地对文件进行多次写入
问题描述
我需要在 Go 中将多行写入文件。这些行将由另一种方法生成。因此,要写入文件,我想写入文件的次数与行数一样多。但是写入文件是一项昂贵的操作。我正在考虑一种非常乐观的写入文件的方式。我可以在这里使用什么数据结构?
解决方案
要分摊操作系统文件读取和写入的成本,请使用 Go 标准库bufio
包。
这里有一个 Go 基准来说明这一点:bufio
速度要快得多。
$ go test bufio_test.go -bench=.
goos: linux
goarch: amd64
BenchmarkBufioWrite-4 50 20887474 ns/op 6774811 B/op 147938 allocs/op
BenchmarkOSWrite-4 3 387543398 ns/op 6022413 B/op 104415 allocs/op
$
bufio_test.go
:
package main
import (
"bufio"
"io/ioutil"
"os"
"strings"
"testing"
)
func BenchmarkBufioWrite(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for N := 0; N < b.N; N++ {
out, err := ioutil.TempFile(``, `StackOverflow`)
if err != nil {
b.Fatal(err)
}
outName := out.Name()
w := bufio.NewWriter(out)
for _, line := range benchLines {
_, err := w.Write([]byte(line))
if err != nil {
b.Fatal(err)
}
}
err = w.Flush()
if err != nil {
b.Fatal(err)
}
err = out.Close()
if err != nil {
b.Fatal(err)
}
os.Remove(outName)
}
}
func BenchmarkOSWrite(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for N := 0; N < b.N; N++ {
out, err := ioutil.TempFile(``, `StackOverflow`)
if err != nil {
b.Fatal(err)
}
outName := out.Name()
w := out
for _, line := range benchLines {
_, err := w.Write([]byte(line))
if err != nil {
b.Fatal(err)
}
}
err = out.Close()
if err != nil {
b.Fatal(err)
}
os.Remove(outName)
}
}
var benchLines = func() []string {
// The Complete Works of William Shakespeare by William Shakespeare
// http://www.gutenberg.org/files/100/100-0.txt
data, err := ioutil.ReadFile(`/home/peter/shakespeare.100-0.txt`)
if err != nil {
panic(err)
}
return strings.Split(string(data), "\n")
}()
推荐阅读
- javascript - 如何通过 JavaScript 列出 Chrome 中的所有网络摄像头?
- node.js - Models.Address 不是 Node Js 中的构造函数
- html - 使用样式隐藏/删除 HTML 表格跨度元素
- ios - 我的 Xcode 可以构建,但 Fastlane 不行
- c# - 如何修复模型中的 IEnumerable 错误?
- javascript - 制作图像滑块但最后一张图像没有循环结束
- sqlite - Sqlite如何执行以-something结尾的单词的搜索
- user-interface - 树脂模拟/基于颜色的背景
- node.js - Typescript 引用如何与构建和 Docker 交互?
- c# - 执行可以处理所有大量文档的原始查询 mongo driver c#