Golang: How do I determine the number of lines in a file efficiently?

后端 未结 3 672
我寻月下人不归
我寻月下人不归 2020-12-04 13:29

In Golang, I am looking for an efficient way to determine the number of lines a file has.

Of course, I can always loop through the entire file, but does not seem ver

3条回答
  •  北荒
    北荒 (楼主)
    2020-12-04 14:09

    The most efficient way I found is using IndexByte of the byte packet, it is at least four times faster than using bytes.Count and depending on the size of the buffer it uses much less memory.

    func LineCounter(r io.Reader) (int, error) {
    
        var count int
        const lineBreak = '\n'
    
        buf := make([]byte, bufio.MaxScanTokenSize)
    
        for {
            bufferSize, err := r.Read(buf)
            if err != nil && err != io.EOF {
                return 0, err
            }
    
            var buffPosition int
            for {
                i := bytes.IndexByte(buf[buffPosition:], lineBreak)
                if i == -1 || bufferSize == buffPosition {
                    break
                }
                buffPosition += i + 1
                count++
            }
            if err == io.EOF {
                break
            }
        }
    
        return count, nil
    }
    

    Benchmark

    BenchmarkIndexByteWithBuffer  2000000          653 ns/op        1024 B/op          1 allocs/op
    BenchmarkBytes32k             500000          3189 ns/op       32768 B/op          1 allocs/op
    

提交回复
热议问题