Как эффективно сделать несколько записей в файл - PullRequest
0 голосов
/ 10 декабря 2018

Мне нужно написать несколько строк в файл в Go.Эти строки будут сгенерированы другим методом.Итак, чтобы записать в файл, я подумал о том, чтобы сделать столько же записей в файл, сколько строк.Но запись в файл является дорогостоящей операцией.Я думаю об очень оптимистичном способе записи в файл.Какую структуру данных я мог бы использовать здесь?

1 Ответ

0 голосов
/ 10 декабря 2018

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