且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

写作业成本[Go lang]

更新时间:2023-09-24 10:59:22

bufio 包已经创建完全适合这类任务。在进行系统调用之前,不要为每个Write调用创建一个系统调用。 bufio.Writer 在内部存储器中缓冲到固定数量的字节。在系统调用之后,内部缓冲区被重新用于下一部分数据。



与第二种方法比较 bufio.Writer


  • 使更多的系统调用( N / S 而不是 1

  • 使用较少的内存( S 字节而不是 N


    其中 S - 是缓冲区大小(可以通过 bufio.NewWriterSize ), N 来指定 - 需要写入的数据的总大小。

    示例用法( https://play.golang.org/ p / AvBE1d6wpT ):

      f,err:= os.Create(file.txt)
    if err!= nil {
    log.Fatal(err)
    }
    推迟f.Close()

    w:= bufio.NewWriter(f)
    fmt.Fprint(w,Hello,)
    fmt.Fprint(w,world!)
    err = w.Flush()//别忘了刷新!
    if err!= nil {
    log.Fatal(err)
    }


    I have a Go program which writes strings into a file.I have a loop which is iterated 20000 times and in each iteration i am writing around 20-30 strings into a file. I just wanted to know which is the best way to write it into a file.

    • Approach 1: Keep open the file pointer at the start of the code and write it for every string. It makes it 20000*30 write operations.

    • Approach 2: Use bytes.Buffer Go and store everything in the buffer and write it at the end.Also in this case should the file pointer be opened from the beginning of the code or at the end of the code. Does it matter?

    I am assuming approach 2 should work better. Can someone confirm this with a reason. How does writing at once be better than writing periodically. Because the file pointer will anyways be open. I am using f.WriteString(<string>) and buffer.WriteString(<some string>) buffer is of type bytes.Buffer and f is the file pointer open.

    bufio package has been created exactly for this kind of task. Instead of making a syscall for each Write call bufio.Writer buffers up to a fixed number of bytes in the internal memory before making a syscall. After a syscall the internal buffer is reused for the next portion of data

    Comparing to your second approach bufio.Writer

    • makes more syscalls (N/S instead of 1)
    • uses less memory (S bytes instead of N bytes)

    where S - is buffer size (can be specified via bufio.NewWriterSize), N - total size of data that needs to be written.

    Example usage (https://play.golang.org/p/AvBE1d6wpT):

    f, err := os.Create("file.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()
    
    w := bufio.NewWriter(f)
    fmt.Fprint(w, "Hello, ")
    fmt.Fprint(w, "world!")
    err = w.Flush() // Don't forget to flush!
    if err != nil {
        log.Fatal(err)
    }