首页 文章

如何有效地对文件进行多次写入

提问于
浏览
0

我需要在Go中为一个文件写多行 . 这些行将由另一种方法生成 . 因此,要写入文件,我想要对文件执行尽可能多的写入行数 . 但是写入文件是一项代价高昂的操作 . 我正在考虑一种非常乐观的写入文件的方式 . 我可以在这里使用什么数据结构?

1 回答

  • 2

    要分摊操作系统文件读取和写入的成本,请使用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")
    }()
    

相关问题