分享
  1. 首页
  2. 文章

Golang 逐行读取大文件性能对比

51reboot · · 8236 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。


前 言

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 函数

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 函数

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
}

技术交流QQ群:368573673

有兴趣的可以关注我们的微信公众号:Reboot51


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:51reboot

查看原文:Golang 逐行读取大文件性能对比

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
8236 次点击 ∙ 2 赞
4 回复 | 直到 2020年03月24日 03:01:09
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏