日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

java字符串表表容量_java – 我可以使用什么符号表来存储~50 mil的字符串,快速查找而不会耗尽堆空间?...

發布時間:2023/12/19 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java字符串表表容量_java – 我可以使用什么符号表来存储~50 mil的字符串,快速查找而不会耗尽堆空间?... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我有一個約5000萬字符串的文件,我需要在啟動時添加到某種符號表中,然后以合理的速度搜索幾次.

我嘗試使用DLB trie,因為查找會相對較快,因為所有字符串都是< 10個字符,但在填充DLB時,我會得到超出GC開銷限制或outofmemory - 堆空間錯誤.使用HashMap發現了相同的錯誤.這是一個由分級器編譯和運行的賦值,所以我寧愿不只是分配更多的堆空間.是否有不同的數據結構可以減少內存使用,同時仍然有合理的查找時間?

解決方法:

如果您期望低前綴共享,那么trie可能不是您的最佳選擇.

由于您只在啟動時加載查找表一次,并且您的目標是內存占用率低且查找速度“合理”,因此最佳選擇可能是排序數組和二進制搜索查找.

首先,將數據加載到數組中.由于您可能不知道前面的大小,因此您將加載到ArrayList中.然后從列表中提取最終數組.

假設您加載了5000萬個10個字符的字符串,內存將是:

10 character string:

String: 12 byte header + 4 byte 'hash' + 4 byte 'value' ref = 24 bytes (aligned)

char[]: 12 byte header + 4 byte 'length' + 10 * 2 byte 'char' = 40 bytes (aligned)

Total: 24 + 40 = 64 bytes

Array of 50 million 10 character strings:

String[]: 12 byte header + 4 byte 'length' + 50,000,000 * 4 byte 'String' ref = 200,000,016 bytes

Values: 50,000,000 * 64 bytes = 3,200,000,000 bytes

Total: 200,000,016 + 3,200,000,000 = 3,400,000,016 bytes = 3.2 GB

當您轉換ArrayList< String>時,您將需要另一個String []副本. to String []. Arrays.sort()操作可能需要50%的數組大小(~100,000,000字節)用于臨時存儲,但如果在排序之前為GC發布了ArrayList,則可以重用該空間.

因此,總需求約為3.5 GB,僅適用于符號表.

現在,如果空間確實非常珍貴,你可以擠壓它.如您所見,String本身在64字節中增加了24字節的開銷.您可以使符號表直接使用char [].

此外,如果您的字符串都是US-ASCII或ISO-8859-1,則可以將char []轉換為byte [],從而節省一半的字節.

組合在一起,將值大小從64字節減少到32字節,總符號表大小從3.2 GB減少到1.8 GB,或在加載期間大約2 GB.

UPDATE

假設輸入的字符串列表已經排序,下面是如何執行此操作的示例.作為MCVE,它只使用一個小的靜態數組作為輸入,但您可以輕松地從文件中讀取它們.

public class Test {

public static void main(String[] args) {

String[] wordsFromFile = { "appear", "attack", "cellar", "copper",

"erratic", "grotesque", "guitar", "guttural",

"kittens", "mean", "suit", "trick" };

List wordList = new ArrayList<>();

for (String word : wordsFromFile) // Simulating read from file

wordList.add(word.getBytes(StandardCharsets.US_ASCII));

byte[][] symbolTable = wordList.toArray(new byte[wordList.size()][]);

test(symbolTable, "abc");

test(symbolTable, "attack");

test(symbolTable, "car");

test(symbolTable, "kittens");

test(symbolTable, "xyz");

}

private static void test(byte[][] symbolTable, String word) {

int idx = Arrays.binarySearch(symbolTable,

word.getBytes(StandardCharsets.US_ASCII),

Test::compare);

if (idx < 0)

System.out.println("Not found: " + word);

else

System.out.println("Found : " + word);

}

private static int compare(byte[] w1, byte[] w2) {

for (int i = 0, cmp; i < w1.length && i < w2.length; i++)

if ((cmp = Byte.compare(w1[i], w2[i])) != 0)

return cmp;

return Integer.compare(w1.length, w2.length);

}

}

產量

Not found: abc

Found : attack

Not found: car

Found : kittens

Not found: xyz

標簽:java,memory

來源: https://codeday.me/bug/20190608/1199027.html

總結

以上是生活随笔為你收集整理的java字符串表表容量_java – 我可以使用什么符号表来存储~50 mil的字符串,快速查找而不会耗尽堆空间?...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。