Чтобы амортизировать стоимость операций чтения и записи файлов операционной системы, используйте стандартную библиотеку 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")
}()