亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 bufio.NewScanner 逐行讀取文件時的性能問題

使用 bufio.NewScanner 逐行讀取文件時的性能問題

Go
慕森王 2022-07-11 15:55:19
我正在學習如何在 Go 中有效地讀取非常大的文件。我已經嘗試過bufio.NewScanner并bufio.NewReader使用ReadString('\n'). 在這兩個選項中,NewScanner似乎始終更快(2:1)。因為NewScanner我發現逐行讀取文件比運行 unix cat 命令讀取文件需要更多時間。我測量了運行這段代碼需要多長時間:package mainimport (    "bufio"    "fmt"    "os")func main() {     file, _ := os.Open("test")     scanner := bufio.NewScanner(file)     for scanner.Scan() {        fmt.Println(scanner.Text())     }}當您與常規 unixcat輸出進行比較時,我得到以下結果:$ time ./parser3 > /dev/null       19.13 real        13.81 user         5.94 sys$ time cat test > /dev/null        0.83 real         0.08 user         0.74 sys幾次執行之間的時間差是一致的。我知道掃描'\n'會增加開銷,而不是像 cat 那樣將數據從輸入復制到輸出。但是看到和這段代碼片段之間的區別,cat我問自己這是否是在 Go 中逐行讀取文件的最有效方法。
查看完整描述

2 回答

?
30秒到達戰場

TA貢獻1828條經驗 獲得超6個贊

根據 MuffinTop 的評論,這是提高速度的代碼片段。性能損失與 Scanner 的使用無關,而是與以下事實有關:

  1. 不在輸出中使用緩沖

  2. 使用scanner.Text()-which 分配一個字符串 - 而不是scanner.Bytes()

添加輸出緩沖的性能:

package main


import (

    "bufio"

    "fmt"

    "os"

)


func main() {


     file, _ := os.Open("test")

     w := bufio.NewWriter(os.Stdout) 

     scanner := bufio.NewScanner(file)

     for scanner.Scan() {

        fmt.Fprintln(w, scanner.Text())

     }


}

上述解決方案使用輸出緩沖,耗時 6.6 秒,而原來的 19.1 秒


添加輸出緩沖和使用.Bytes()而不是.Text()輸出的性能:


package main


import (

    "bufio"

    "fmt"

    "os"

)


func main() {


     file, _ := os.Open("test")

     w := bufio.NewWriter(os.Stdout) 

     scanner := bufio.NewScanner(file)

     for scanner.Scan() {

        w.Write(scanner.Bytes()); w.WriteByte('\n')

     }


}

上述解決方案使用輸出緩沖并從掃描儀輸出字節,并且需要 2.2 秒,而原來的 19.1 秒。


查看完整回答
反對 回復 2022-07-11
?
弒天下

TA貢獻1818條經驗 獲得超8個贊

首先考慮您將讀取 CSV、JSON 的數據類型,以及將讀取它的系統以及為什么?必須考慮所有這些細節。沒有一種適合所有人的方式,最好的開發人員知道如何right tool使用job. 在不知道 ram 限制、數據等的情況下不清楚。我們會從服務器讀取大量 JSON 嗎?或者我們會解析一個小文本文件,通常每個函數都有一個目的。不要養成認為一種方式比另一種更好或更差的習慣,并限制你的學習和技能。

讀取文件的方法。


  • 文檔解析

  • 從文件中讀取所有數據并將其轉換為對象。


  • 流解析

  • 一次讀取一個元素,然后移動到下一個元素。

有些方法可能更快,但它會將整個文件讀入內存如果你的文件太大怎么辦?

或者如果您的文件不是那么大,尋找重復的名稱怎么辦?如果您逐行掃描文件,也許如果您正在搜索多個項目,那么逐行閱讀是最好的方式嗎?

你應該看看這篇文章。特別感謝@Schwern,他已經在這里回答了您的問題。使用字節和掃描儀稍微快一些。見:鏈接

I found that using scanner.Bytes() instead of scanner.Text() improves speed

 slightly on my machine.  bufio's scanner.Bytes() method 

doesn't allocate any additional memory, whereas Text() creates a string from its buffer.


查看完整回答
反對 回復 2022-07-11
  • 2 回答
  • 0 關注
  • 374 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號