第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

Go如何提高逐行讀取大文件的速度

Go如何提高逐行讀取大文件的速度

Go
喵喔喔 2023-06-12 16:21:43
我試圖找出逐行讀取大文件并檢查該行是否包含字符串的最快方法。我正在測試的文件大小約為 680mb:    package main        import (        "bufio"        "fmt"        "os"        "strings"    )        func main() {        f, err := os.Open("./crackstation-human-only.txt")            scanner := bufio.NewScanner(f)        if err != nil {            panic(err)        }        defer f.Close()            for scanner.Scan() {            if strings.Contains(scanner.Text(), "Iforgotmypassword") {                fmt.Println(scanner.Text())            }        }    }構(gòu)建程序并在我的機器上計時后,它運行了 3 秒以上 ./speed  3.13s user 1.25s system 122% cpu 3.563 total增加緩沖區(qū)后buf := make([]byte, 64*1024)scanner.Buffer(buf, bufio.MaxScanTokenSize)它變得更好一點 ./speed  2.47s user 0.25s system 104% cpu 2.609 total我知道它會變得更好,因為其他工具可以在一秒鐘內(nèi)完成它而無需任何類型的索引。這種方法的瓶頸似乎是什么?0.33s user 0.14s system 94% cpu 0.501 total
查看完整描述

3 回答

?
元芳怎么了

TA貢獻(xiàn)1798條經(jīng)驗 獲得超7個贊

最后編輯


這是對花費微不足道的時間的問題的“逐行”解決方案,它會打印整個匹配行。


package main


import (

    "bytes"

    "fmt"

    "io/ioutil"

)


func main() {

    dat, _ := ioutil.ReadFile("./jumble.txt")

    i := bytes.Index(dat, []byte("Iforgotmypassword"))

    if i != -1 {

        var x int

        var y int

        for x = i; x > 0; x-- {

            if dat[x] == byte('\n') {

                break

            }

        }

        for y = i; y < len(dat); y++ {

            if dat[y] == byte('\n') {

                break

            }

        }

        fmt.Println(string(dat[x : y+1]))

    }

}

real    0m0.421s

user    0m0.068s

sys     0m0.352s

原始答案


如果您只需要查看字符串是否在文件中,為什么不使用正則表達(dá)式呢?


注意:我將數(shù)據(jù)保存為字節(jié)數(shù)組而不是轉(zhuǎn)換為字符串。


package main


import (

    "fmt"

    "io/ioutil"

    "regexp"

)


var regex = regexp.MustCompile(`Ilostmypassword`)


func main() {

    dat, _ := ioutil.ReadFile("./jumble.txt")

    if regex.Match(dat) {

        fmt.Println("Yes")

    }

}

jumble.txt是一個 859 MB 的包含換行符的混亂文本。


運行time ./code我得到:


real    0m0.405s

user    0m0.064s

sys     0m0.340s

為了嘗試回答您的評論,我不認(rèn)為瓶頸本質(zhì)上來自于逐行搜索,Golang 使用一種有效的算法來搜索字符串/符文。


我認(rèn)為瓶頸來自IO讀取,當(dāng)程序從文件讀取時,它通常不會在讀取隊列中排在第一位,因此,程序必須等到可以讀取才能開始實際比較。因此,當(dāng)您一遍又一遍地閱讀時,您將被迫等待輪到您的 IO。


給你一些數(shù)學(xué),如果你的緩沖區(qū)大小是 64 * 1024(或 65535 字節(jié)),你的文件是 1 GB。將 1 GB / 65535 字節(jié)除以檢查整個文件所需的 15249 次讀取。在我的方法中,我“一次”讀取整個文件并檢查構(gòu)造的數(shù)組。


我能想到的另一件事就是遍歷文件所需的循環(huán)總數(shù)以及每個循環(huán)所需的時間:


給定以下代碼:


dat, _ := ioutil.ReadFile("./jumble.txt")

sdat := bytes.Split(dat, []byte{'\n'})

for _, l := range sdat {

    if bytes.Equal([]byte("Iforgotmypassword"), l) {

        fmt.Println("Yes")

    }

}

我計算出每個循環(huán)平均需要 32 納秒,字符串 Iforgotmypassword 在我的文件中的第 100000000 行,因此這個循環(huán)的執(zhí)行時間大約是 32 納秒 * 100000000 ~= 3.2 秒。


查看完整回答
反對 回復(fù) 2023-06-12
?
暮色呼如

TA貢獻(xiàn)1853條經(jīng)驗 獲得超9個贊

H. Ross's answer is awesome,但它會將整個文件讀入內(nèi)存,如果你的文件太大,這可能不可行。如果您仍然想逐行掃描,也許如果您正在搜索多個項目,我發(fā)現(xiàn)使用 scanner.Bytes() 而不是 scanner.Text() 可以稍微提高我機器上的速度,從 2.244s 到原題,1.608s。bufio 的 scanner.Bytes() 方法不分配任何額外的內(nèi)存,而 Text() 從其緩沖區(qū)創(chuàng)建一個字符串。


package main


import (

    "bufio"

    "fmt"

    "os"

    "bytes"

)


// uses scanner.Bytes to avoid allocation.

func main() {

    f, err := os.Open("./crackstation-human-only.txt")


    scanner := bufio.NewScanner(f)

    if err != nil {

        panic(err)

    }

    defer f.Close()


    toFind := []byte("Iforgotmypassword")


    for scanner.Scan() {

        if bytes.Contains(scanner.Bytes(), toFind) {

            fmt.Println(scanner.Text())

        }

    }

}


查看完整回答
反對 回復(fù) 2023-06-12
?
慕俠2389804

TA貢獻(xiàn)1719條經(jīng)驗 獲得超6個贊

使用我自己的 700MB 測試文件和你的原始文件,時間剛剛超過 7 秒


使用 grep 是 0.49 秒


使用這個程序(不打印出行,它只是說是)0.082 秒


package main


import (

    "bytes"

    "fmt"

    "io/ioutil"

    "os"

)


func check(e error) {

    if e != nil {

        panic(e)

    }

}

func main() {

    find := []byte(os.Args[1])

    dat, err := ioutil.ReadFile("crackstation-human-only.txt")

    check(err)

    if bytes.Contains(dat, find) {

        fmt.Print("yes")

    }

}


查看完整回答
反對 回復(fù) 2023-06-12
  • 3 回答
  • 0 關(guān)注
  • 277 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號