3 回答

TA貢獻1840條經驗 獲得超5個贊
您的結構在內存方面非常低效,讓我們看看內部結構。但在此之前,快速提醒一些 go 類型所需的空間:
布爾值:1 個字節
整數:4 字節
uintptr:4 字節
[N]類型:N*sizeof(type)
[]type: 12 + len(slice)*sizeof(type)
現在,讓我們看看你的結構:
type node struct {
root bool // 1 byte
b []byte // 12 + len(slice)*1
output bool // 1 byte
index int // 4 bytes
counter int // 4 bytes
child [256]*node // 256*4 = 1024 bytes
fails [256]*node // 256*4 = 1024 bytes
suffix *node // 4 bytes
fail *node // 4 bytes
}
好的,你應該猜到這里發生了什么:每個節點的重量都超過 2KB,這是巨大的!最后,我們將查看用于初始化 trie 的代碼:
func (m *Matcher) buildTrie(dictionary [][]byte) {
max := 1
for _, blice := range dictionary {
max += len(blice)
}
m.trie = make([]node, max)
// ...
}
你說你的字典是 4 MB。如果總共是 4MB,那么就意味著在 for 循環結束時,max = 4MB. 它包含 4 MB 不同的單詞,然后max = 4MB*avg(word_length).
我們將采用第一個場景,最好的一個。您正在初始化一個 4M 節點的切片,每個節點使用 2KB。是的,這需要一個不錯的 8GB。
您應該查看如何構建您的 trie。從與 Aho-Corasick 算法相關的維基百科頁面中,每個節點包含一個字符,因此從根開始最多有 256 個字符,而不是 4MB。
一些使其正確的材料:https ://web.archive.org/web/20160315124629/http://www.cs.uku.fi/~kilpelai/BSA05/lectures/slides04.pdf

TA貢獻2037條經驗 獲得超6個贊
該node
類型的內存大小為2084
字節。我寫了一個小程序來演示內存使用情況:https: //play.golang.org/p/szm7AirsDB
如您所見,三個字符串(大小為 11(+1) 個字節)dictionary := []string{"fizz", "buzz", "123"}
需要 24 MB 內存。
如果您的字典有 4 MB 的長度,您將需要大約4000 * 2084 = 8.1 GB
內存。
因此,您應該嘗試減小字典的大小。
- 3 回答
- 0 關注
- 691 瀏覽
添加回答
舉報