前 言
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