2 回答

TA貢獻1810條經(jīng)驗 獲得超5個贊
這是一種不太難也不太慢的方法,使用bytes.IndexByte(因為你發(fā)現(xiàn) Go 的 asm 實現(xiàn)有幫助)和syscall.Mmap:
package main
import (
"bytes"
"fmt"
"log"
"os"
"syscall"
)
func main() {
if len(os.Args) < 2 {
log.Fatal("pass filename on command line")
}
f, err := os.Open(os.Args[1])
if err != nil {
log.Fatal("open: ", err)
}
stat, err := f.Stat()
if err != nil {
log.Fatal("stat: ", err)
}
data, err := syscall.Mmap(int(f.Fd()), 0, int(stat.Size()), syscall.PROT_READ, syscall.MAP_SHARED)
if err != nil {
log.Fatal("mmap: ", err)
}
newlines := 0
for {
i := bytes.IndexByte(data, 10)
if i == -1 {
break
}
newlines++
data = data[i+1:]
}
fmt.Println(newlines)
}
Mmap 看起來很奇怪,但在這里就像您將文件讀入一個切片一樣,除了由于操作系統(tǒng)的幫助而占用的資源較少。
您可以在沒有太多工作的情況下并行計數(shù),但我不確定這是否值得。(amd64例如,如果單核計數(shù)受到內(nèi)存帶寬的限制,如果增益為零或負值,我不會感到震驚,但這對我來說測試速度并不快。)
- 2 回答
- 0 關(guān)注
- 177 瀏覽
添加回答
舉報