golang 在#golang中逐行读取文件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang 在#golang中逐行读取文件相关的知识,希望对你有一定的参考价值。
Golang逐行读取大文件性能对比
BUFIO 是什么?
BUFIO 是用来驱动 I/O 列内的专用时钟网络,这个专用的时钟网络独立于全局时钟资源,适合采集源同步数据。BUFIO 只能由位于同一时钟区域的 Clock-Capable I/O驱动。一个时钟区域有4个 BURIO,其中的2个可以驱动相邻区域的 I/O 时钟网络。BUFIO 不能驱动逻辑资源(CLB、BRAM等),因为 I/O 时钟网络只存在于 I/O 列中。
简单点就是:
bufio 包实现了带缓存的 I/O 操作
它封装一个 io.Reader 或 io.Writer 对象
使其具有缓存和一些文本读写功能
本文主要来对比一下 BUFIO 中的 ReadString 和 ReadLine 函数的性能。
注:测试代码忽略读取内容和错误处理
ReadString 代码:
func ReadString(filename string) {
f, _ := os.Open(filename)
defer f.Close()
r := bufio.NewReader(f)
for {
_, err := r.ReadString('\n')
if err != nil {
break
}
}
}
ReadLine 代码:
func ReadLine(filename string) { f, _ := os.Open(filename) defer f.Close() r := bufio.NewReader(f) for { _, err := readLine(r) if err != nil { break } } }
此函数主要解决单行字节数大于4096的情况
func readLine(r *bufio.Reader) (string, error) {
line, isprefix, err := r.ReadLine()
for isprefix && err == nil {
var bs []byte
bs, isprefix, err = r.ReadLine()
line = append(line, bs...)
}
return string(line), err
}
注: 测试文件 log 每行字节数均大于4096
以上两种方式分别读取10G/20G/30G文件的耗时如下:
读取10G文件耗时
readstring:30.717832767s
readline:27.358268244s
读取20G文件耗时
readstring:59.937901346s
readline:54.871384854s
读取30G文件耗时
readstring:1m21.657831495s readline:1m13.222376352s
ReadLine 读取文件更快,原因是由于 ReadString 后端调用 ReadBytes,而 ReadBytes 多次使用 copy 方法造成大量耗时。
测试代码如下:
package main import ( "bufio" "fmt" "os" "time" )
func main() { filename := "./log" s := time.Now() ReadString(filename) e1 := time.Now() fmt.Printf("readstring:%v\n", e1.Sub(s)) ReadLine(filename) e2 := time.Now() fmt.Printf("readline:%v\n", e2.Sub(e1)) }
func ReadString(filename string) { f, _ := os.Open(filename) defer f.Close() r := bufio.NewReader(f) for { _, err := r.ReadString('\n') //忽略内容 if err != nil { break } } }
func ReadLine(filename string) { f, _ := os.Open(filename) defer f.Close() r := bufio.NewReader(f) for { _, err := readLine(r) if err != nil { break } } }
func readLine(r *bufio.Reader) (string, error) { line, isprefix, err := r.ReadLine() for isprefix && err == nil { var bs []byte bs, isprefix, err = r.ReadLine() line = append(line, bs...) } return string(line), err }
完
Golang 实战班第2期火热报名进行中
招生要求:
有Linux基础,有志于使用 Go 语言做分布式系统编程的人员,想往系统架构师方向发展的同学。BAT 架构师带你一起飞。
课程内容:
Golang入门
Golang程序结构
Golang的基础数据类型
Golang复合数据类型
Golang的函数
Golang的方法
Golang的接口
Golang的协程和Channel
Golang基于共享变量的并发
Golang包和工具
上课模式:网络直播班 线下面授班
咨询报名联系:
QQ(1):979950755 小月
QQ(2):279312229 ada
WeChat : 1902433859 小月
WeChat : 1251743084 小单
开课时间:9月23日(周六)
课程大纲:http://51reboot.com/course/go/
(阅读原文,即可跳转)
以上是关于golang 在#golang中逐行读取文件的主要内容,如果未能解决你的问题,请参考以下文章